Using VBScript to manipulate a MSI files and the Golden Rules

This blog entry provides an introduction to using VBScript to manipulate MSI files, and the golden rules that should be followed.

It forms part 1 of an 17-part series that explores how to use VBScript to manipulate MSI relational databases using the Windows Installer API.  Throughout this series of tutorials, we identify the common issues that we encounter and the best practises that we use to overcome them.

An MSI (Microsoft Installer) is a relational database that contains multiple tables which reference each other using foreign keys constraints. We can use a simplified form of SQL to extract data from these tables – Windows Installer SQL.

Windows Installer SQL provides a vastly reduced selection of built-in functions and join operations. For example, it doesn’t contain string functions such as ‘Left‘ and ‘Right‘, we can’t use ‘LIKE‘ operators and wildcards for string comparisons, and we’re limited to Inner Joins only.

We have made the ‘MSI Scripting Golden Rules’ below, which highlights common mistakes when using Windows Installer SQL:

MSI Scripting Golden Rules

■  Golden Rule 1: Windows Installer SQL is case-sensitive:

SELECT * FROM `Registry` is correct.

SELECT * FROM `registry` is incorrect.

This applies to column names too.

SELECT `Key` FROM `Registry` is correct.

SELECT `key` FROM `Registry` is incorrect.

■  Golden Rule 2: Be careful when using single quotes and backticks. Single quotes (‘) are used to enclose string comparisons, and backticks (`) are used to enclose column/table names:

SELECT * FROM `Registry` WHERE `Key` = ‘SOFTWARE\alkaneTest’ is correct.

SELECT * FROM ‘Registry’ WHERE `Key` = ‘SOFTWARE\alkaneTest’ is incorrect.

SELECT * FROM `Registry` WHERE `Key` = `SOFTWARE\alkaneTest` is incorrect.

■  Golden Rule 3: Be careful when using single quotes for comparisons! Use them for STRING comparisons, don’t use them for INTEGER comparisons!

SELECT `Key` FROM `Registry` WHERE `Root` = 2 is correct.

SELECT `Key` FROM `Registry` WHERE `Root` = ‘2’ is incorrect. The Root column is an Integer data type!

■  Golden Rule 4: It is NOT possible to update primary key columns. The only alternative is to use the Modify method and msiViewModifyReplace action.

■  Golden Rule 5: Do not try inserting/updating if you have not opened the database in transact mode!

■  Golden Rule 6: Do not try inserting/updating (Eg, opening in transact mode) an MSI when the MSI is open (Eg, in Orca)!

■  Golden Rule 7: When you insert/update colums, make sure you set values for nullable fields!

■  Golden Rule 8: If you’re creating an object in a Custom Action, do NOT use the WScript directive! Use CreateObject, not WScript.CreateObject!

Dim oInstaller : Set oInstaller = CreateObject(“WindowsInstaller.Installer”) is correct.

Dim oInstaller : Set oInstaller = WScript.CreateObject(“WindowsInstaller.Installer”) is incorrect.

■  Golden Rule 9: If you’re not sure about table names, column names and data types consult the online SDK or your local copy of MSI.chm

■  Golden Rule 10: Always close your View objects after using them (with View.Close()) and dispose of Record, Database and Installer objects by setting them to Nothing.

Thanks for reading the introduction to using VBScript to manipulate MSI files, and the golden rules that should be followed.  Next you can find out how to read a registry value from a table using VBScript.