Razorback
NewsProjectsGuidesResourcesContact
 Guide Index Quick Links


The UpdateInis Directive

Created on March 10, 2023

Contents
  1. Adding Entries
  2. Deleting Entries

The INF setup engine includes its own mechanism for modifying other INI files. INI files are regarded as easier to manage, though the lines in an UpdateInis section require a syntax that may get kind of hard to read at times. This page will cover the essentials as well as clarify a few ambiguous-looking things, especially in regards to quote marks.

Unlike with files and the registry, there are not two directives for adding and deleting entries in INI files. There is only one directive that manages it all.

Adding Entries

The syntax here isn't too complicated; each line addresses a new or existing entry in a section of an INI file. The parameters are as follows, from left to right:

  • File - The full path to the INI file to work with. You can use string expansion with LDIDs here.
  • Section - The section of an INI file to work inside of. Much like in INFs, section headers in INI files are enclosed in square brackets ([]).
  • Old Entry - Specify an INI entry by either its key or value, or both. An asterisk can be specified for the key or value to match multiple entries. It's written in the format key=value
  • New Entry - Used for changing an old entry or adding in a new one. It's written in the same format as the old entry.
  • Flags - Used to control how this line is executed. If left empty, the default behavior is to either overwrite the existing old entry if it matches the existing key/field, or add in a new entry if the old entry parameter is left blank.

For our purposes, we'll define a new section for managing INI entries labeled New.Ini, with the trailing .Ini being a convention for indicating what this section is used for.

[DefaultInstall]
CopyFiles=Files.Copy
AddReg=New.Reg
UpdateInis=New.Ini

Because you're going to be working with a file, you have to tell the INF to point to it. You can technically write this as you normally would:

[New.Ini]
C:\TEST.INI,NewSect,,"Great=GARAGE SALE !"

However, the string expansion discussed earlier also works with LDIDs, and you don't have to (and shouldn't) define them in a Strings section. If you want to work with the INI file located at the root of the drive where Windows is installed, write this:

[New.Ini]
%24%\TEST.INI,NewSect,,"Great=GARAGE SALE !"

It's always good practice to use LDIDs to ensure you get consistent results across varied Windows installations. When you execute an installation, the INF should call the New.Ini section to create or update the TEST.INI file at the root of the drive, returning something like this:

[NewSect]
Great=GARAGE SALE !

The operation was executed exactly how we wanted it to be... was it? Our program using the INI file may prefer to have the value surrounded in quote marks. Doing that within quote marks themselves sounds outlandish when there's no proper-looking escaping mechanism like in a programming language such as C, but you can write two adjacent quote marks to output a literal quote mark.

%24%\TEST.INI,NewSect,,"Great=""GARAGE SALE !"""

And you should see that your entry in TEST.INI now has quote marks surrounding the value. You can pass this same literal quote mark to registry values as well. Also note that it did not create a new key with the same name, only updated the existing one. It is considered invalid to have duplicate labels for entries in a section.

If you want a value to be updated only on the condition it matches a key or value, specify something for the old entry parameter. To match only the key, use this:

%24%\TEST.INI,NewSect,"Great=*","Great=""GARAGE SALE ?"""

To match only the value, write this:

%24%\TEST.INI,NewSect,"*=""GARAGE SALE !""","Great=""GARAGE SALE ?"""

To match both the key and value, write this:

%24%\TEST.INI,NewSect,"Great=""GARAGE SALE !""","Great=""GARAGE SALE ?"""

While it looks like you'd get the same effect as before, if the key and/or value did not exist in the section based on the conditions you've given, the replacement entry would not be created. Try deleting TEST.INI and execute the installation with such conditions applied; all you would get is the header for the section NewSect.

Deleting Entries

Deleting INI entries should be simple enough, but because only one directive is used for managing INI entries, you cannot use the same UpdateInis section for both installation and uninstallation as you'd want to. It is necessary to create a new section for this task. We'll define our new section as Uninstall.Ini, and you'll notice that I leave the parameter for the new entry empty:

[Uninstall]
DelFiles=First.Del,Second.Del
DelReg=Goodbye.DelReg
UpdateInis=Uninstall.Ini

[Uninstall.Ini]
%24%\TEST.INI,NewSect,"Great=*"

After executing an uninstallation, you should see in TEST.INI that the entry is gone, leaving NewSect empty.

To delete an entry only on the condition that both the key and value match what exists in the section, you need to apply the flag 1 at the last parameter, which is written as:

%24%\TEST.INI,NewSect,"Great=""GARAGE SALE !""",,1

Using this flag, the entry is not touched if the value is GARAGE SALE ?, but will be deleted if it has an exclamation point instead.

The setup engine is not capable of deleting sections. If you really need to clean out an INI file, your best bet is to delete it in a DelFiles directive. Never delete INIs integral to Windows, such as WIN.INI or SYSTEM.INI.

If you're wanting to modify INI files via a batch script using a simpler method, you may wish to try my own command line program, Infsect.

Here is what our INF file looks like now:

[Version]
Signature="$CHICAGO$"

[SourceDisksNames]
1="Source Files",,0,files

[SourceDisksFiles]
test.txt = 1
other.txt = 1

[DestinationDirs]
DefaultDestDir=10
Files.Copy=10,NEWDEST\FILES
First.Del=10,NEWDEST\FILES
Second.Del=10,NEWDEST\FILES

[DefaultInstall]
CopyFiles=Files.Copy
AddReg=New.Reg
UpdateInis=New.Ini

[Uninstall]
DelFiles=First.Del,Second.Del
DelReg=Goodbye.DelReg
UpdateInis=Uninstall.Ini

[Files.Copy]
test.txt,,,16
offline.txt,other.txt,,16

[New.Reg]
HKCU,NEWKEY\TEST,,,"Bill Gates"
HKCU,NEWKEY\TEST,"Members",,"Robinson Hoodlum"
HKCU,NEWKEY\TEST,"How Tall",1,00,22,44,66,88,AA,CC,EE
HKCU,NEWKEY\TEST\LEVEL3,"none",1,46
HKCU,%OurKey%,"Online",,%WHEATIES%
HKCU,%OurKey%,"AlterEgo",,"%PerfectBeing%"

[New.Ini]
%24%\TEST.INI,NewSect,,"Great=""GARAGE SALE !"""

[First.Del]
test.txt

[Second.Del]
offline.txt

[Goodbye.DelReg]
HKCU,NEWKEY\TEST,"Members"
HKCU,NEWKEY\TEST\LEVEL3

[Uninstall.Ini]
%24%\TEST.INI,NewSect,"Great=""GARAGE SALE !""",,1

[Strings]
OurKey="NEWKEY\TEST"
WHEATIES="ROCK ON CHICAGO"
PerfectBeing="Tripod Sardine"

Don't forget to leave whitespace at the end of the file.


Comments

flatrute - March 17, 2023 at 10:29 AM

There are a few specification documents on the compression algorithm which in theory would let me be able to build a replacement that scales better on modern systems but I am so busy in college at the time I am typing this...

1 comment on this page

Sort: Ascending | Descending

Leave a Comment

Name: (required)

Website: (optional)

Maximum comment length is 1000 characters.
First time? Read the guidelines

SORRY NOT GONNA SHOW THIS IN TEXT BROWSER
Enter the text shown in the image: