Advanced Custom Action Conditions
by Doug Glen

Introduction:
MS Custom Actions (CA) are usually straightforward scripting tasks. However powerful the scripts are though they need to be run only in the context they are needed. Some CAs are meant to be used only during the install or uninstall. Others might need to run if a certain feature has been selected or if a system search is used to check for a file, INI entry or registry entry.

This document outlines several conditions and how they are used. It does not cover every situation but it should be able to guide you in the right direction to find the set of conditions you need for your solution with Wise installation products. (Note: Conditions can vary for InstallShield based applications.)

Conditions vs InstallLevels:
Although you can use InstallLevels as a means to select features it is the difference between a hammer and toothpick. Anything assigned that InstallLevel or less will be installed. This is usually a means to differentiate between Typical, Complete or Custom install selections. Conditions on the other hand can be used to toggle individual features or even components in the installation.

AND / OR Conditions:
These two conditions can be confusing to newcomers at first. When using the AND condition it means that both conditions on each side of the AND must be ‘true’ in order for the statement to be true. OR on the other hand is true if either condition on each side of it is true, then the entire statement is true. When you need to combine both types of statements you can nest them in the script editor or when editing them in Wise you can use parentheses to separate the commands (This AND that) OR Something. In the script editor this would appear like:

If (This AND That) OR Something
Do some action
End

Property setting discovery:
In order to set conditions you must know the value of the property, feature name or component name. This is easy enough if you are creating the MSI yourself. MSIs from other sources can be problematic. To work through this situation you should enable logging of the MSI during your initial setup, capture or configuration of the target MSI. The logs will show all the property settings of the MSI at the end of the log file. There you can find the value it contains when the program was run.

Condition Table:
This MSI table can be used to control feature InstallLevels. The first column contains information on the feature selection, the second is the InstallLevel to be set when the conditions in the third column are met.

Most Commonly used conditions:

Run on initial installation only:
NOT Installed

Run on initial install or when repair is selected.
NOT Installed OR MaintenanceMode=”Modify”

Run when being uninstalled from command line or add / remove menu.
REMOVE=~”All” OR MaintenanceMode=”Remove”

The first portion of the condition is true when used from the menu while the other is true if used from the command line. When the /x option is passed to the msiexec.exe it sets the MaintenanceMode to “Remove” while when selecting Remove from the add/remove menu the property REMOVE is set to “ALL”.

Statement locations:
The position of statements using these conditions vary. Most commonly they will be placed after the CostFinalize action or after the InstallFinalize actions. Actions such as RemoveExistingProduct which by default is placed after the InstallFinalize action should be moved to just after the CostFinalize action to properly upgrade applications. CAs needing conditions based on the system search, feature or component conditions must be after the CostFinalize action. It is after this action that the state of these features or component will be known.

In most situations the above conditions will be the only ones you will ever use. When building custom in house MSIs this may not be true and you will need to use a more advanced set of conditions.

Advanced Custom Actions and Conditions:
Using conditions to enable or disable Features or Components.
The Windows Installer SDK has a section called ‘Conditional Statement Syntax’ where all the conditions you can use are outlined. These can enable or disable features or components. They can also be used to determine the state of each. By state I refer to if it is set to be installed, not installed, or no action has been yet determined. Because the state is not finalized until the CostFinalize action as occurred, all conditional statements must occur after this action in the MSI.

Symbol Table:

Symbol Representation
% Environment-variable (value)
$ component-action (what action)
? component-state (what state is selected)
& feature-action (what action)
! feature-state (what state it is in)

Note that there is a symbol for what action will be taken, and a symbol for what state. This is an important distinction and allows you to determine the type of condition being used at a glance.

Condition State Table:

State Value Assigned Comments
Unknown -1 No action is selected or being taken
Advertised 1 Not available for components
Absent 2 Not present
Local 3 On local system or selected for Installation
Source 4 Run from source

Great, now we have all this information, what do we do with it? Experiment with it. That is how I had to do it originally. But that somewhat defeats the purpose of this paper since I don’t want you to have to re-invent the wheel. So without further ado….

If a feature is selected for installation:
&feature_name=3
This will be true if the feature_name is selected for installation.

If a feature is not selected for installation:
NOT &feature_name=3

The feature is already installed:
!feature_name=3

And of course using the NOT operator you can check to see if it was not already installed.

This last condition example can be handy when trying to determine if the feature is installed and you are doing a remove action. This allows you to run a CA during the uninstall that does a special action if a certain feature is installed.

Although you can use these same values for components it is not wise to do so if you must have the component installed. It should only be used if you don’t want to install a second copy of the same component. This is because if you are testing to see if the component will be installed and an existing component is already installed on the system it will return false rather than true.

Truth or Consequences:
When evaluating conditions you should not try to tie all the conditions on one line. It may not be possible to do so when you have a mix of AND and OR conditions. Instead use parentheses in order to group the conditions so they will match better. The following in an example of how this is accomplished.

IF (&feature_name=3 AND Property=value) OR (!feature_name OR MaintenanceMode=”Modify”)

Written out using a truth table this becomes (1 and 1) OR (1 OR 1). The first set of conditions mean both must be met OR either condition in the second statement is true. They can be entered like this in the condition builder in Wise, and then they will write it into the action section without you having to figure out how it should be written.

Using the System search feature and Condition Table:
The System Search feature will search for files, INI values and registry entries during the initialization phase of the install. You can either choose to create a “hard” coded property value or a transient value which is judged to be null if the object is not found, or true if the object is found. The property is created if the item is found otherwise it remains empty and null. When using the System Search you should place the property on the first dialog screen to see if your search was successful. If it is, the value will be displayed on screen, otherwise you will see no changes. This value needs to be placed in the control text of the dialog and enclosed with brackets as with any other variable used. Of course you should remove it after you have verified your search terms are correct.

For example the table can be used to evaluate a property or the Search variable as shown below in Figure 1.


Figure 1

In this example the CLIENT property is assigned in the property table as CLIENT=0. This value is changed on the command line for use in a silent install via SMS. Otherwise the features are selected when the appropriate dialog is displayed and the user makes a selection.

CONFIG_DAT is the search term and is enabled if the search finds the item which in this example is actually a file.

Feature Install Level Condition

Figure 2

The condition table is broken down into three columns as shown in both examples. The feature column holds the name of the feature as it is known to the install. The second column holds the install level to be assigned to the feature if the condition is true. The third table holds the conditions which are used to trigger a true or false condition.

When using the condition table for this purpose you can set the feature during the initial setup to be a custom Install Level or leave it at the default of 3. This only affects the appearance of the feature in the selection dialog to be enabled or disabled (a Install Level higher than 3). So in this example if the file is found the Configuration_File_Install is set to 3 and enabled for installation. If the file is not found then the Configuration_File_Install feature is set to 4 and would appear with a red X on it. This feature may also be hidden from view so the end user never sees if it is enabled or disabled.

This particular example was drawn from a custom in house application that had 5 different clients to be used in 5 different departments. So by default all of the features were set to Install Level 4 so they are disabled initially. It also had to be selectable by command line, or manually selected if manually installed. So the condition table was used to trigger which client was installed because each client was separated by feature. The GUI install would show all of the selections disabled by default and the end user would simply select one of them for installation.

Controlling the Add / Remove application title:
Because this application bundled 5 different clients on the system it meant I should change the title of the application as it appeared in the Add / Remove menu. This was done with the following code snippet:


Figure 3

About the Author:
Doug Glenn is the proprietor and Senior Engineer for FORUM Information Services ™. FIS now operates a support web site (http://foruminfosystems.com) for Wisescript source code and other system utilities that Doug as written including the popular Hotfix Installer. This program installs patches and hotfixes for Windows operating system and applications. Doug has been packaging applications using Wise products since 1999 and has packaged several hundred applications since he first started creating MSI packages. FIS also owns and operates a technical and social commentary web site (http://wildhair.org) where the utilities were originally posted.

Doug Glenn – Å  2005