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

投稿者: | 2016-02-01

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