How can you ensure that MSI package has been built properly and the package structure is correct? Run validation on MSI package.
Validation of MSI packages checks the MSI-file database for authoring errors, because a package installation that does not pass the validation can damage user’s system. Taking into account the importance of the creating error-free MSI packages, we’ll review the principles of MSI package validation, the process itself, and also talk about how to fix MSI errors.
Principles of MSI Package Validation
According to MSDN, MSI package validation includes the following three processes:
- Internal Validation is performed in real time while you are editing MSI table records. This kind of validation checks if entered data is syntactically correct. Specifications for this validation are maintained in _Validation table.
- String-Pool Validation. The Windows Installer stores all database strings in a single shared string pool to reduce the size of the database and to improve performance. The only means of validating the string pool is to use the “MsiInfo” tool found in the Windows Installer SDK.
- Internal Consistency Evaluators – ICEs is a scan of MSI database for entries in database records that are valid but that may cause incorrect behavior in the context of the whole database.
What Are the Internal Consistency Evaluators (ICEs)
Internal consistency evaluators, also called ICEs, are custom actions written in VBScript, JScript, or as a DLL or EXE. ICE custom actions return four kinds of messages:
Error messages report database elements that cause incorrect behaviour. For example, duplicate component GUIDs cause the installer to incorrectly register components.
Warning messages report database elements that cause incorrect behaviour in certain cases. Warnings can also report unexpected side effects of database authoring, for example, entering the same property name in two conditions that differ only by the case of letters in the name. As the installer is case-sensitive, the installer treats these as different properties.
Failure messages report the failure of an ICE custom action. Failure is commonly caused by a database with such severe problems that the ICE cannot even run.
- Informational messages
Informational messages provide information from the ICE and do not indicate a problem with the database. Often they inform about the ICE itself, such as a brief description. They can also provide progress information as the ICE runs.
ICEs check the MSI package database for the violation of rules. Many of these violations are serious, such as component IDs duplication in the same package or a component ID with lowercase letters. All errors reported by an ICE validator should be fixed, and you should pay attention to all the warnings.
For full ICEs description please read ICE Reference in MSDN.
Validating MSI Package against Standard and Custom CUB files
After selecting the appropriate ICEs for MSI package validation, you must collect the custom actions together into an ICE database – a .cub file. A .cub file is a standard .msi database that contains only ICEs and their required tables and is used only to store and provide access to ICE custom actions.
A .cub file contains the following database tables:
|Binary||The script files, DLLs, and EXEs of the ICE customs actions that are referenced in the CustomAction table.|
|CustomAction||Each record in this table corresponds to an ICE custom action included in the .cub file.|
|_ICESequence||This table lists the ICE customs actions included in the .cub file in their execution sequence.|
|_Validation||This table contains the .cub file entries that are to be merged into the _Validation table.|
|_Special||Any special processing tables required by particular ICE custom actions must be included in the .cub file. The names of these tables must have a leading underscore.|
As .cub file is an MSI by nature, it can be created (opened/changed) with any MSI-editing tool – e.g. MSI Editor (try it now for free).
To validate a database, at first a .cub is merged to the database, then ICEs are executed and the results of execution are reported. Most ICE validation tools merge the .cub file and your database into a third, temporary database. Windows Installer displays warnings, errors, debugging information, and API errors as it executes each ICE in the .cub file. When the installer finishes executing the ICEs it closes the .msi file, .cub file, and temporary database without saving any changes. The .msi file and .cub file remain unchanged by the validation test.
Microsoft supplies several .cub files in the Microsoft Windows Software Development Kit (SDK):
- darice.cub – provides Full MSI Validation(all standard ICEs)
- logo.cub – provides validation against Windows Logo Program requirements
- XPlogo.cub – provides validation against Windows XP Logo Program
- Vstalogo.cub – provides validation against Windows Vista Logo Program
- Mergemod.cub – provides validation of merge modules
Authors of installation packages can write own ICE custom actions, providing specific checks that apply to their packages. In this case, custom .cub files are designed to provide specific validation.
When performing the validation in MSI Editor, go to Menu -> Validation – two .cub files are provided for selection via menu – “darice.cub” (Full MSI validation suite) and “Mergemod.cub” (Merge module validation suite):
You can also validate the MSI using a custom CUB file.
During the validation process, you generally get some errors and warnings – relevant tables(1) and fields(2) are marked with red color, and complete information about particular problem is given on ICE Validation(3) tab:
When validation process is finished, it is time to review MSI package validation results and resolve validation problems where appropriate.
Fixing ICE Validation Errors
First, we have to mention that not all MSI package validation errors/warnings are critical. You have to consider the criticality of each one and decide whether to fix it or not.
The process of fixing validation errors implies making changes to installation database in order to achieve the state when they can pass the validation. Package functionality, on the other hand, should not suffer during the process. Therefore, sometimes fixing ICE errors is a matter of compromise.
MSI package validation issues are fixed one-by-one. In some cases, the same database entries are the subject of more than one issue, so few validation problems can be fixed with a single change in the database. Fixing ICE errors is an iterative process, as changes made to the database to fix particular errors can result in new validation issues. So “fixed” database must be revalidated at each iteration, until the desired results of validation are achieved.
The Review of the Common Validation Errors
|ICE||Description||Severity||How to fix it|
|ICE02||Validates that certain references between the Component, File, and Registry tables are reciprocal||Error (should be fixed)||Component column of File or Registry table should be changed to contain the appropriate component|
|ICE03||Validates the data types and foreign keys based on the _Validation table and the database tables in the .msi file||Error (should be fixed)||Massive MSI package validation is performed. May result in many possible errors. Correction is done based on the reported error, and is obvious from the error’s description.|
|ICE04||Validates that the sequence number of every file in the File table is less than or equal to the largest sequence number in the LastSequence column of the of the Media table||Error (should be fixed)||Occurs when files are added to MSI manually without updating Media table. Sequence fields for files in scope, or LastSequence field of Media table are changed to correlate with each other.|
|ICE05||Validates that certain tables contain required entries||Error (should be fixed)||Validation error is descriptive enough to make required amendments.|
|ICE07||Validates that installation package specifies that fonts be installed into the FontsFolder||Warning (can be ignored)||Some fonts should be installed in application’s folders, so this error can be just ignored. Otherwise, Directory_ field of relevant component is changed to system Fonts directory.|
|ICE08||Validates that the Component table contains no duplicate GUIDs||Error (should be fixed)||Unique GUIDs are generated to eliminate all duplicates.|
|ICE09||Validates that the permanent bit is set for every component marked for installation into the SystemFolder||Warning (can be ignored)||You may ignore this error for files that you are 100% sure belong to the current application only and are not shared with other applications. Such files should not fall under the SystemFolder in case of good application design, but still appear very often. You may set SharedDllRefCount attribute for the particular component to make the deletion of such files safer.|
|ICE18||Validates that any empty directories used as a key path for a component are listed in the CreateFolder table||Error (should be fixed)||An entry with directory – component pair must be added to the CreateFolder table.|
|ICE21||Validates that every component in the Component table belongs to a feature||Error (should be fixed)||An entry with feature – component pair must be added to the FeatureComponents table.|
|ICE30||Validates that the installation of components containing the same file never installs the file more than once in the same directory||Error (can be ignored)||Relevant files should have unique names (both short and long) in FileName column of File table. The error can be ignored if files belong to the different components that are conditioned with mutually exclusive conditions (Condition field of the Component table).|
|ICE33||Validates that the all the entries in the Registry table belong in that table. It issues a warning for each Registry table entry that should be moved and suggests the appropriate table||Warning (can be ignored)||Registry entries should be moved to the appropriate tables (Class, ProgId etc.) if advertising of those entries is required. Additionally, registry data may be insufficient/non consistent to fill the appropriate tables completely, thus, it cannot be moved out of the Registry table. Special attention is required when Registry table contains entries, which belong to the same objects defined in advertising tables. In this case, entries in the Registry table may overwrite data posted by advertising tables.|
|ICE38||Validates that every component is being installed under the current user’s profile also specifies a registry key under the HKEY_CURRENT_USER root in the KeyPath column of the Component table||Error (can be ignored)||Appropriate key path is selected for the component. Key path may be specifically created under HKCU for that purpose only. The error can be ignored under particular circumstances if this was intended by package design.|
|ICE39||Validates the Summary Information Stream of the database||Error (should be fixed)||Summary info should be filled adequately. This is vital.|
|ICE46||Checks for custom properties in conditions, formatted text, and other locations that differ from a system defined property only by the case of one or more characters||Error (should be fixed)||Custom properties should be renamed to avoid duplicates.|
|ICE57||Validates that individual components do not mix per-machine and per-user data||Error (should be fixed)||Per-machine and per-user data must be moved to separate components. New components can be created if required.|
|ICE64||Checks that new directories in the user profile are removed correctly in roaming scenarios||Error (should be fixed)||Relevant directories should be written to the RemoveFile table.|
|ICE77||Verifies that custom actions with the msidbCustomActionTypeInScript bit set are sequenced after the InstallInitialize action and before the InstallFinalize action||Error (should be fixed)||Sequence for relevant custom action must be changed, to fall in the specified range.|
|ICE88||Validates that the directory referenced in the DirProperty column of the IniFile table exists in the Windows Installer package||Error (should be fixed)||DirProperty field in the IniFile table should be set to existing folder. Alternatively, an appropriate folder must be created in the Directory table.|
|ICE91||Posts a warning if a file, .ini file, or shortcut file is installed into a per-user only directory||Warning (can be ignored)||Generally ignored, as it usually occurs when a file should be installed under the given path. You may overcome this by usage of DuplicateFile table.|
Now, you are equipped with all the necessary information about MSI package validation. Practice fixing validation errors in your packages and do not forget to use the information above and information from ICE Reference.