November 30th, 2004

Can I Edit .INI Files Using a Script?

Hey, Scripting Guy! Question

Hey, Scripting Guy! Can I edit.INI files using a script?

— MZ

SpacerHey, Scripting Guy! AnswerScript Center

Hey, MZ. Yes, you can edit .INI files (or any kind of text files, for that matter) using a script. The method you have to use might not be the most elegant process in the world, but it’ll work. And that’s all we really care about, right?

Before we get into the whys and wherefores of editing .INI files, let’s take a look at a sample file. This happens to be a section of the .INI file for Adobe Reader, although most .INI files will look similar:

[OEM Install]
DisplayWelcomeDlg=YES
DisplayEULA=NO
DisplayTypeOfInstallDlg=NO
DisplaySelectDestDirDlg=YES
DisplayCustomDlg=NO
DisplayUserInfoDlg=NO
DisplayConfirmRegDlg=NO
DisplayStartCopyDlg=NO
DisplayFinishDlg=NO
DisplayFinalMessage=YES
DisplayRebootDlg=YES
ProgGroupName=
DefaultDestDir=
UserName=
UserCompanyName=
UserSerialNumber=

Suppose we want to do two things to this file: we want to change DisplayWelcomeDlg to NO, and we want to set the UserName to Ken Myer. Ideally, we’d write a script that would simply search the file for DisplayWelcomeDlg and change the assigned value to NO, search for the UserName property and set the value to Ken Myer, and then save the changes. Unfortunately, the FileSystemObject – the technology we need to use to read and modify text files – doesn’t have those capabilities. Instead, we’ll have to edit the .INI file by brute force. That probably doesn’t make much sense to you at the moment, but hopefully you’ll understand what we mean by the time you reach the end of this column.

Let’s show you the completed script, and then we’ll explain how it works:

Const ForReading = 1
Const ForWriting = 2

Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objTextFile = objFSO.OpenTextFile(“sample.ini”, ForReading)

Do Until objTextFile.AtEndOfStream strNextLine = objTextFile.Readline

intLineFinder = InStr(strNextLine, “DisplayWelcomeDlg”) If intLineFinder <> 0 Then strNextLine = “DisplayWelcomeDlg=NO” End If

intLineFinder = InStr(strNextLine, “UserName”) If intLineFinder <> 0 Then strNextLine = “UserName=Ken Myer” End If

strNewFile = strNewFile & strNextLine & vbCrLf Loop

objTextFile.Close

Set objTextFile = objFSO.OpenTextFile(“sample.ini”, ForWriting)

objTextFile.WriteLine strNewFile objTextFile.Close

We start off by defining two constants: ForReading and ForWriting. These two constants will be required when we read and write to the .INI file. Note that there isn’t a constant called ForEditing; that’s because the FileSystemObject doesn’t allow you to both read and write a file at the same time. Instead, we’ll have to open the file and read it, then we’ll have to close the file and re-open it for writing. At that point, we’ll be able to save our changes. Like we said, it’s not the most elegant system ever devised, but, hey, it is what it is.

After defining the two constants we open our .INI file (sample.ini) for reading. We then set up a Do loop in which we’ll read the file line-by-line, until there is nothing left to read (when the AtEdnOfStream property is TRUE). We start by using the Readline method to read the first line of the file, and store that line in the variable strNextLine.

Now the fun begins. As we noted earlier, the FileSystemObject doesn’t really allow you to search a file; instead, we have to read the file line-by-line, then individually check each line to see if it happens to be of interest. That’s exactly what we’re doing with this line of code:

intLineFinder = InStr(strNextLine, “DisplayWelcomeDlg”)

This code uses the InStr method to see if the string DisplayWelcomeDlg can be found anywhere within the variable strNextLine (and, remember, this variable contains the .INI line we just read in). InStr works by reporting the character position at which the target string is found. For example, suppose strNextLine equaled this:

xxxxxDisplayWelcomeDlgxxxxx

In that case, InStr would return a 6, because our target string starts at the sixth position (we have 5 x’s, then we have DisplayWelcomeDlg). If the target string can’t be found, then InStr returns a 0.

And that’s exactly what happens when we read the first line of the .INI file. Because the first line in the file is [OEM Install], InStr returns a 0. Consequently, we skip our first If-Then statement, and continue on. We then check to see if UserName can be found anywhere in the variable. Again, InStr returns a 0, so we skip the second If-Then statement as well.

This is what we mean by editing the file using brute force: we’re checking each and every line of the file for each of our test conditions. Suppose we wanted to modify the DisplayUserInfoDlg property, too. Well, then we’d have to add a third test condition, one similar to this:

intLineFinder = InStr(strNextLine, “DisplayUserInfoDlg”)

Got that? We’ve now checked the first line of the .INI file, and it isn’t a line of interest. So do we just discard it and move on? Nope, not quite. Instead, we use this line of code:

strNewFile = strNewFile & strNextLine & vbCrLf

What this code does is construct a brand-new .INI file in memory, storing this new file in the variable strNewFile. The first time we run through the loop, strNewFile will consist of everything currently in strNewFile (which is nothing the first time through) plus whatever happens to be in the variable strNextLine ([OEM Install]) plus a carriage return linefeed (vbCrLf). In other words, after one iteration strNewFile looks like this:

[OEM Install]

Exciting, isn’t it?

Now we loop around and read the second line in the text file (DisplayWelcomeDlg=YES). And guess what: this time InStr finds the target string, and the variable intLineFinder will equal 1 (because DisplayWelcomeDlg begins in the first character position). Because intLineFinder does not equal 0, we now enter our first If-Then block. Inside that block, we simply change the value of strNewLine:

strNextLine = “DisplayWelcomeDlg=NO”

Now our variable doesn’t contain the text we read in from the .INI file; instead, it contains this modified text:

DisplayWelcomeDlg=NO

In other words, we didn’t really edit the value of the DisplayWelcomeDlg property. Instead, we simply threw out the old line and replaced it with a brand-new line. However, the end result is no different than it would have been had we’d been able to edit the property value directly.

When we get to the end of the loop, the variable strNewFile will now look like this:

[OEM Install]
DisplayWelcomeDlg=NO

See how this works? We’ll keep reading through the .INI file line-by-line, and we’ll keep constructing the variable strNewFile line-by-line as well. By the time the script is finished, strNewFile will contain this information:

[OEM Install]
DisplayWelcomeDlg=NO
DisplayEULA=NO
DisplayTypeOfInstallDlg=NO
DisplaySelectDestDirDlg=YES
DisplayCustomDlg=NO
DisplayUserInfoDlg=NO
DisplayConfirmRegDlg=NO
DisplayStartCopyDlg=NO
DisplayFinishDlg=NO
DisplayFinalMessage=YES
DisplayRebootDlg=YES
ProgGroupName=
DefaultDestDir=
UserName=Ken Myer
UserCompanyName=
UserSerialNumber=

And, yes, that is exactly the same information we want in our modified .INI file.

We’re on our way now. We next close the file sample.ini, then immediately reopen it for writing (silly, but that’s what we have to do). We then use this single line of code to replace the existing text in sample.ini with the information stored in the variable strNewFile:

objTextFile.WriteLine strNewFile

When we close the file again, the data will be saved, and we will have successfully modified our .INI file.

Now, we don’t claim this is the coolest piece of code ever written; it’s not. And there might very well be .INI files where this doesn’t work. But the truth is, it’s probably the best you’re going to be able to do, at least with the tools built into the operating system.


Author

0 comments

Discussion are closed.