読者です 読者をやめる 読者になる 読者になる

Fioの素敵な日々

日々の出来事や何やらをつれづれに

【Script】VBScriptでINIファイルの読み書きを行う

WSHには、レジストリの読み書きのメソッドは存在するのですが、INIファイルについてはサポートされていません。

けれども、「レジストリを汚したくない」という言葉が存在する通り、今でも、設定をINIファイルで行うことへのこだわりはなくなっていません。

ということで、ずいぶん昔に作ったINIファイルの読み書きクラスです。まずはテスト用の部分を。

Dim INI
Set INI = New IniFile
INI.FilePath=Replace(WScript.ScriptFullName, WScript.ScriptName, "test.ini")
INI.WriteString "Section", "Key", "Value1"
INI.WriteString "Section", "Key2", "Value2"

MsgBox INI.ReadString("Section", "Key", "")
MsgBox INI.ReadString("Section", "Key2", "Error")
INI.Update 'なくても終了時に保存します。
Set INI = Nothing

次がクラスの部分です。クラスを使用するようにしたのは、スクリプトを閉じる時に自動的にINIファイルを保存するようにできるからです。

Class IniFile
  Private fso,f

  Private IniFilePath  'Path to the ini File
  Private Section  '[section]
  Private Key  'Key=Value
  Private Default  'Return it when an error occurs
  Private Content

  Private Sub Class_Initialize   ' Setup Initialize event.
    Default=""
    Set fso=CreateObject("Scripting.FileSystemObject")
  End Sub
  Private Sub Class_Terminate   ' Setup Terminate event.
    Call Update
    Set fso=Nothing
  End Sub
  
  Property Let FilePath(FileName)
    IniFilePath = FileName
    If fso.FileExists(IniFilePath) Then
      Set f=fso.OpenTextFile(IniFilePath,1)
      Content=f.ReadAll
      f.close
      Set f=Nothing
    Else
      Content=""
    End If
  End Property

  Public Sub Update()
    'Create a brand new ini file
    Set f=fso.CreateTextFile(IniFilePath,True)
    f.Write Content
    f.close
    Set f=Nothing
  End Sub

  Private Property Get ContentArray()
    'All the file in an array of lines
    ContentArray=Split(Content,vbCrLf,-1,1)
  End Property

  Private Sub FindSection(ByRef StartLine, ByRef EndLine)
    Dim x,A,s
    StartLine=-1
    EndLine=-2
    A=ContentArray
    For x=0 To UBound(A)
      s=UCase(Trim(A(x)))
      If s="[" & UCase(section) & "]" Then
        StartLine=x
      Else
        If (Left(s,1)="[") And (Right(s,1)="]") Then
          If StartLine>=0 Then
            EndLine=x-1
            If EndLine>0 Then 'A Space before the next section ?
              If Trim(A(EndLine))="" Then EndLine=EndLine-1
            End If
            Exit Sub
          End If
        End If
      End If
    Next
    If (StartLine>0) And (EndLine<0) Then EndLine=UBound(A)
  End Sub

  Private Property Get Value()
    'Retrieve the value for the current key in the current section
    Dim x,i,j,A,s
    FindSection i,j
    A=ContentArray
    Value=Default
    'Search only in the good section
    For x=i+1 To j
      s=Trim(A(x))
      If UCase(Left(s,Len(Key)))=UCase(Key) Then
        Select Case Mid(s,Len(Key)+1,1)
        Case "="
          Value=Trim(Mid(s,Len(Key)+2))
          Exit Property
        Case " ",chr(9)
          x=Instr(Len(Key),s,"=")
          Value=Trim(Mid(s,x+1))
          Exit Property
        End Select
      End If
    Next
  End Property
  Private Property Let Value(sValue)
    ' Write the value for a key in a section
    Dim i,j,A,x,s,f
    FindSection i,j
    If i<0 Then 'Session doesn't exist
      Content=Content & vbCrLf & "[" & section & "]" & vbCrLf & Key & "=" & sValue
    Else
      A=ContentArray
      f=-1
      'Search for the key, either the key exists or not
      For x=i+1 To j
        s=Trim(A(x))
        If UCase(Left(s,Len(Key)))=UCase(Key) Then
          Select Case Mid(s,Len(Key)+1,1)
          Case " ",chr(9),"="
            f=x  'Key found
            A(x)=Key & "=" & sValue
          End Select
        End If
      Next
      If f=-1 Then
        'Not found, add it at the end of the section
        Redim Preserve A(UBound(A)+1)
        For x=UBound(A) To j+2 Step -1
          A(x)=A(x-1)
        Next
        A(j+1)=Key & "=" & sValue
      End If
      'Define the content
      s=""
      For x=0 To UBound(A)  
        s=s & A(x) & vbCrLf
      Next
      'Suppress the last CRLF
      If Right(s,2)=vbCrLf Then s=Left(s,Len(s)-2)
      Content=s  'Write it
    End If
  End Property
  
  Public Sub WriteString(sSection, sKey, sValue)
    Section = sSection
    Key = sKey
    Value = sValue
  End Sub
  
  Public Function ReadString(sSection, sKey, sDefault)
    Section = sSection
    Key = sKey
    Default = sDefault
    ReadString = Value
  End Function
  
End Class 
広告を非表示にする