Dwarfsoft [GPA]

Ini File Handler for VBScript

by on Feb.27, 2009, under Scripting, Work


Print This Post Print This Post

I was recently working on an issue to do with managing .ini files in VBScript. I know what you are all going to say now: Why would you use an INI file when the registry is available for use?! Well, there is one instance that you may wish to use another form of configuration or information passing. In this instance we have an initiation of the Ghost Store method for the System Volume. To achieve a store on the system volume we require the PC to be rebooted and it then boots up into a BartPE environment to run the Ghost Store, and perform a few custom tasks. Therefore, the System Volumes Registry is not present (or requires mounting then reading, which has proven somewhat unreliable for me in the past).

So, the reason it came to developing the Ini file handler class is due to the need to provide some more controlled smarts into the store/restore system. Clusters, such as the one I work within, can be more proactive in their maintenance, and therefore require more advanced features than the corporate stock-standard release is likely to contain. As such the area in which I work is constantly involved in working towards a very automated maintenance process. My skills, lying within scripting, programming, and automation in particular, come in handy in this regard. I regularly disassemble the corporate releases to ensure that they will not break when released out into the wild of our corporate machines.

The store/restore process was one that I had previously tackled and modified due to the limitations of the corporate model. Unfortunately this modification was temporary, as the updated software that was released from corporate changed the model under which the store/restore process was to operate, and caused the modifications we had made locally to break.

The easiest way of reading Ini files in Windows is to use the Word.Application Object (as gathered quickly for demonstration from here):

Set objWord = CreateObject("Word.application")
WinDir = objWord.System.PrivateProfileString(FileName , Section , Key)

This, however, does not work in BartPE. Instead, I have developed a class that can be added into a VBScript and used very easily. It utilizes Dictionaries to keep the settings organised. This means that if it reads two settings in the same section with the same name, the value will reflect the last one (the one closest to the end of the file).

The full source of the IniFile handler are as follows:

Class IniFile
   Private mIniFile
   '
   '----------------------- Sub Load -------------------------------
   Public Sub Load(Filename)
      LoadIni FileName,False
   End Sub
   '-------------------- End of Sub Load ---------------------------
 
   Public Sub LoadIni(Filename,JustDefaults)
     Dim objFSO, objDictionary, objSubDictionary, file, ini, arr, line, splitline, tmpsplit  
     Set objFSO = CreateObject("Scripting.FileSystemObject")
 
     Set objDictionary = mIniFile
     Set objDictionary = CreateObject("Scripting.Dictionary")
     Set objSubDictionary = Nothing
     Set mIniFile = objDictionary
     If JustDefaults Then
        Read = False
     Else
        Read = True
     End If
 
     If objFSO.FileExists(Filename) Then
        Set file = objFSO.OpenTextFile(Filename)
        ini = file.ReadAll()
        file.Close 
 
        arr = Split(ini,vbCrLf)
        For Each line in arr
           If line = "##STARTDEFAULT" Then
              Read = True
           End If
           If Read Then
              If Left(Trim(Line),1) = "[" And Right(Trim(Line),1) = "]" Then
                 line = replace(replace(line,"[",""),"]","")
                 If Not IsEmpty(objDictionary.Item(line)) Then
                    Set objSubDictionary = objDictionary.Item(line)
                 Else
 
                    Set objSubDictionary = CreateObject("Scripting.Dictionary")
                    'objDictionary.Add line, objSubDictionary
                    set objDictionary.Item(line) = objSubDictionary
                 End If
              Else
                 If TypeName(objSubDictionary) = "Nothing" or IsEmpty(objSubDictionary) Then
                    Set objSubDictionary = CreateObject("Scripting.Dictionary")
                    objDictionary.Add "[]",objSubDictionary
                    Set objDictionary.Item("[]") = objSubDictionary
                 End If
                 If Left(Trim(line),1) = "#" Then
                    objSubDictionary.Item( "[" & objSubDictionary.Count & "]") = Trim(line)
                 Else
                    splitline = split(Trim(line),"=")
 
                    If TypeName(splitline) <> "Nothing" Then
                       If UBound(splitline) = 1 Then
                          tmpsplit = split(splitline(1), "#")
                          ' Resolve a <value>=<blank> error
                          If UBound(tmpsplit) >= 0 Then
                             objSubDictionary.Item(Trim(splitline(0))) = Trim(tmpsplit(0)) 
                          Else
                             objSubDictionary.Item(Trim(splitline(0))) = ""
                          End If
                       Else
                         'Error
                       End If
                    End If
                 End If
              End If
              If line = "##ENDDEFAULT" And JustDefaults Then
            MsgBox "End Default"
                 Read = False
                 Exit Sub
              End If
           End If
        Next
     Else 
       Exit Sub
     End If
   End Sub
   '------------------- End of Sub LoadIni -------------------------
 
   '----------------------- Function GetValue -------------------------------
   Public Function GetValue(Section, Value)
      Set objDictionary = mIniFile
      If IsSection(Section) Then
         Set objSubDictionary = objDictionary.Item(Section)
         If IsEmpty(objSubDictionary.Item(Value)) Then
            objSubDictionary.Remove(Value)
         Else
            GetValue = objSubDictionary.Item(Value)
         End If
      End If
   End Function
   '-------------------- End of Function GetValue ---------------------------
 
   '----------------------- Function IsSection ------------------------------
   Public Function IsSection(Section)
      Set objDictionary = mIniFile
      If IsEmpty(objDictionary.Item(Section)) Then
         objDictionary.Remove(Section)
         IsSection = False
      Else
        IsSection = True
      End If
   End Function
   '-------------------- End of Function IsSection --------------------------
 
   '----------------------- Function IsSection ------------------------------
   Public Function Save(FileName)
      Set objDictionary = mIniFile
      Set objFSO = CreateObject("Scripting.FileSystemObject")
      Set Outfile = objFSO.CreateTextFile(FileName)
      If TypeName(objDictionary) <> "Nothing" Then
         If Not IsEmpty(objDictionary.Keys) Then
            For Each Key in objDictionary.Keys
               If Key = "[]" Then
               ElseIf Key = "" Then
               Else
                  Outfile.WriteLine("[" & Key & "]")
               End If
               Set objSubDictionary = Nothing
               If Not IsEmpty(objDictionary.Item(Key)) Then
                  Set objSubDictionary = objDictionary.Item(Key)
               End If
               If TypeName(objSubDictionary) <> "Nothing" Then
                  If Not IsEmpty(objSubDictionary.Keys) Then
                     For Each subKey in objSubDictionary.Keys
                        If Left(subKey,1) = "[" Then
                           OutFile.WriteLine(objSubDictionary.Item(subKey))
                        Else
                           OutFile.WriteLine(subKey & "=" & objSubDictionary.Item(subKey))
                        End If
                     Next
                  End If
               End If
               OutFile.WriteLine
            Next
         End If
      End If
   End Function
   '-------------------- End of Function IsSection --------------------------
 
   '--------------------- Function AddNextNumeric ---------------------------
   Public Function AddNextNumeric(Section,Value)
      Set objDictionary = mIniFile
      If IsEmpty(objDictionary.Item(Section)) Then
         Set objSubDictionary = CreateObject("Scripting.Dictionary")
         Set objDictionary.Item(Section) = objSubDictionary
         objSubDictionary.Item("1") = Value
         AddNextNumeric = 1
      Else
        Set objSubDictionary = objDictionary.Item(Section)
        Number = 1
        Do While IsEmpty(objSubDictionary.Item("" & Number)) 
          Number = Number + 1
        Loop
        objSubDictionary.Item("" & Number) = Value
        AddNextNumeric = Number
      End If
   End Function
   '------------------ End of Function AddNextNumeric -----------------------
 
   '--------------------------- CONSTRUCTOR ---------------------------------
   Private Sub Class_Initialize
      ' Calss Constructor
      ' Initialization goes here
      Set mIniFile = Nothing
' MsgBox TypeName(mIniFile)
   End Sub
   '------------------------- END CONSTRUCTOR -------------------------------
 
   '---------------------------- DESTRUCTOR ---------------------------------
   Private Sub Class_Terminate
      ' Calss Destructor
      ' Cleanup goes here
' MsgBox TypeName(mIniFile)
      Set mIniFile = Nothing
   End Sub
   '-------------------------- END DESTRUCTOR -------------------------------
End Class

Usage of the class for reading Ini files is as follows:

set ifile = New IniFile
ifile.Load("filename.ini")
Variable = ifile.GetValue("Section","Variable")

There are obviously functions in the class that allow for writing out the Ini File and modifying the values. Feel free to play with the code, but please remember to link back to here. I do love my popularity, so any of you who want to link here, please do so.

Cheers, Chris.

:, , , , ,

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!