The Microsoft Windows Installer format is a powerful and robust installation technology but, as is often the case in life, ultimate power does not come without certain responsibilities.
Validation Is Your Responsibility
The MSI database is often likened to the SQL database. Indeed when using the Windows Installer automation interface, the syntax statements are very SQL like, although it is not a full SQL implementation. Therein lies the problem; a full implementation of a relational database within the MSI file would have made the engine too large. Remember the first version had to be distributed on a 1.44Mb floppy disk. This means things like foreign key relationships are not being checked on entry, which in turn means the MSI tables, rows and columns can hide all manner of inconsistent entries. To counter this we validate the built MSI package.
Validation is not new by any means. It predates Windows Installer, though you may not have realised. Before the MSI tables structure, installations were generally controlled by a script which was, at least in part, compiled into an executable. As part of this compilation, the syntax of the script is checked. It was a mandatory part of building the installer and essentially is validation.
The Windows Installer equivalent is called validation and uses a slightly modified MSI file with the extension .CUB (pronounced cube) to hold a number of checking routines known as Internal Consistency Evaluator rules (ICE rules). Collections of these rules come in slightly different varieties covering logo compliance for Windows 2000, Vista and XP as well as the full suite of rules which includes all tests.
Validation can be done within the InstallShield 2012 tool from the build menu as well as from within AdminStudio tools such as Application Manager, Conflict Solver and Package Expert.
If the validation options are not available on your build menu, either you have not yet built the package or the type of validation is not applicable to the type of project you are developing.
Updating the Existing ICE Rules for Windows 7
Although these ICE rules have been around since the inception of Windows Installer, some of the newer innovations have somewhat bypassed the older rule sets you may still be using. You may well have seen this being reported:
ICE27 ERROR Unknown action: ‘MsiConfigureServices’ of InstallExecuteSequence table. Not a standard action and not found in CustomAction or Dialog tables
It says that the action MsiConfigureServices is unknown. Although it is a standard action “now” it is an extension of the standard services tables which became available in Windows Installer v5.0. Or perhaps you have seen this one:
ICE45 WARNING Row ‘ReadyToInstall.InstallNow’ in table ‘Control’ has bits set in the ‘Attributes’ column that are reserved. They should be 0 to ensure compatibility with future installer versions.
It says that the InstallNow push button has some unknown attributes, even though those attributes are known “now”: they assign the UAC control icon to the button.
So unless we obtain an updated .CUB file, these appear to be problems we will just have to live with. However, in these instances, that is not the case. As mentioned earlier the .CUB file is just an MSI file with custom tables, so you can use your favourite MSI editor to open it. When we inspect the content we find that the ICE rules themselves have been written to retrieve their parameters and working values from these custom tables and are not using hard-coding inside the rule itself. We can use this to our advantage.
To update the ICE27 we add the MsiConfigureServices row into the _Action table:
And to update the ICE45 we change the UsedBits column of the _ReservedBits table. Here we change the existing value 8126503 by adding the additional allowed attribute for the UAC shield icon 8388608, giving 16515111.
Of course there are also some rules which are plain annoying. Understandably you may never want to fix or even know about them. Further inspecting the .CUB file we find that the _ICESequence table, which controls which rules are used and in which order, has a Condition column. Inserting a suitable logical condition which can never evaluate to true— for example, “1=0”—essentially turns off that rule.
You may also perform the same trick from InstallShield Tools -> Options -> Validation -> Customize by turning off any rules you want to ignore.
In this article we have explored the motivation for MSI Validation and looked in more depth at the standard .CUB file. In my next article we will discover that we can extend this regime to cater for our own business rules by implementing our own custom logic. Our ultimate aim is to improve our overall package quality.