[ Home | Windows Installer | Creating an ICE ]

Creating an ICE Unit Test

To create your initial ICE:

  1. Identify the database error you wish to identify with your test.
  2. Use WiRunSql.vbs to debug the query that will identify the issue in your database
  3. Take an existing ICE script and save it as a new file
  4. Adjust the banner information to reflect the specifics of your ICE
  5. Add a new row to the Binary table in the CUB to hold your script
  6. Add a new row to the CustomAction table in the CUB to define your ICE
  7. Add a new row to the _ICESequence table to sequence your ICE

To test your ICE:

  1. Use msival2 to test your new ICE.
  2. Correct any errors in your ICE as a result of testing
  3. Use WiStream to update the ICE in the Binary table
  4. Repeat the test

Building your own library of ICEs:

You can start with the shipping CUB files from the MSI SDK to build up your own library of ICEs. However, the CUB files are binary files and don't integrate nicely into a source code control system. However, you can use WiExport.vbs from the MSI SDK to export the entire contents of the CUB file into a set of IDT files that contain the contents of the CUB tables. Then you can use a source code control system to track changes you make to the tables in the CUB by tracking the IDT files.

When you export all the tables, each binary blob of data in the CUB will be exported as files within a folder named after the table. For instance, the ICE described in this example will be stored in <folder>\Binary\rtICE01.vbs.ibd. "ibd" stands for "installer binary data" since MSI doesn't know that your script file is a text file; it only knows it to be a blob of binary stuff. You can incorporate this into a nightly build scenario by keeping the VBS files in source code control and copying them to the .ibd filename where the import process will expect to see the file. To "build" the cub, use WiImport.vbs to recreate the cub fresh from all the IDT files and the associated "binary" data. This lets you preserve the source file in your source code control system as a .vbs file that is copied to the .ibd file for "building" the CUB file.

Similarly, if you have ICEs written in C++, you can have a custom build step for the C++ DLL containing your ICE copy the file to .dll.ibd to prepare it for the import step.

This will allow you to track your library of ICEs in a source code control system as well as incorporate the ICEs shipped from Microsoft. When a new version of the CUB is made available from Microsoft, you can export the tables again and update the IDT files and binary content from MS in your source code control system to incorporate the new changes.

Example ICE:

rtICE01 is an ICE that validates the Key column of the UIText table. There is no ICE in the SDK that validates this table.

The UIText table is used to hold miscellaneous user interface strings that may need to be localized for an installation. The strings are used by the built-in user interface controls provided by Windows Installer.

This test will validate that you have used the proper names for the strings in the Key column. The list of allowed values in the Key column were determined by searching the MSI SDK documentation for any mention of the UIText table as well as consulting the values in the UIText table in the Orca.msi file that comes with the SDK.

This turned up several values mentioned in UIText table of Orca.msi for advertisement of a feature that were not mentioned in the SDK documentation. Bugs have been filed and this documentation error should be corrected in the online docs relatively quickly and in the downloadable SDK docs on the next release of the SDK.

Because the Windows Installer UI is declarative in nature, it is often possible to write ICEs that detect classes of errors as well as specific errors that you might repeatedly make. Use the declarative nature of Windows Installer to your advantage by writing new ICEs that flush out whole classes of errors!

rtICE01.zip sample code