You are on page 1of 13

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 Unknown Advertised Absent Local Source Value Assigned -1 1 2 3 4 Comments No action is selected or being taken Not available for components Not present On local system or selected for Installation 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 dont 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 dont 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
Figure 2

Install Level

Condition

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.

Custom Action Types


Custom Action Type 1 This custom action calls a dynamic link library (DLL) written in C or C++. Source The DLL is generated from a temporary binary stream. The Source field of the CustomAction table contains a key to the . The Data column in the Binary table contains the stream data. A separate stream is allocated for each row. New binary data can be inserted from a file by using MsiRecordSetStream followed by MsiViewModify to insert the record into the table. When the custom action is invoked, the stream data is copied to a temporary file, which is then processed depending upon the type of custom action. Type Value Include the following flag bits in the Type column of the CustomAction table to specify the basic numeric type. Constants msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData Hexadecimal Decimal 0x001 1

Target The DLL is called through the entry point named in the Target field of the CustomAction table, passing a single argument that is the handle to the current install session. The entry point name specified in the table must match that exported from the DLL. Note that if the entry function is not specified by a .DEF file or by a /EXPORT: linker specification, the name may have a leading underscore and a "@4" suffix. The called function must specify the __stdcall calling convention. Return Processing Options Include optional flag bits in the Type column of the CustomAction table to specify return processing options. For a description of the options and the values, see Custom Action Return Processing Options. Execution Scheduling Options Include optional flag bits in the Type column of the CustomAction table to specify execution scheduling options. These options control the multiple execution of custom actions. For a description of the options, see Custom Action Execution Scheduling Options. In-Script Execution Options Include optional flag bits in the Type column of the CustomAction table to specify an inscript execution option. These options copy the action code into the execution, rollback, or commit script. For a description of the options, see Custom Action InScript Execution Options. Return Values Custom Action Return Values. Remarks A custom action that calls a dynamic-link library (DLL) requires a handle to the installation session. If this is also a deferred execution custom action, the session may no longer exist during execution of the installation script. For information on how a custom action of this type can obtain context information, see Obtaining Context Information for Deferred Execution Custom Actions. When a database table is exported, each stream is written as a separate file in the subfolder named after the table, using the primary key as the file name (Name column for the Binary table), with a default extension of ".ibd". The name should use the 8.3 format if the file system or version control system does not support long file names. The

persistent archive file replaces the stream data with the file name used, so that the data can be located when the table is imported.

Custom Action Type 2


This custom action calls an executable launched with a command line. Source The executable is generated from a temporary binary stream. The Source field of the CustomAction table contains a key to the Binary table. The Data column in the Binary table contains the stream data. A separate stream is allocated for each row. New binary data can be inserted from a file by using MsiRecordSetStream followed by MsiViewModify to insert the record into the table. When the custom action is invoked, the stream data is copied to a temporary file, which is then processed depending upon the type of custom action. Type Value Include the following value in the Type column of the CustomAction table to specify the basic numeric type. Constants msidbCustomActionTypeExe + msidbCustomActionTypeBinaryData Hexadecimal Decimal 0x002 2

Target The Target column of the CustomAction table contains the command line string for the executable named in the Source column. Return Processing Options Include optional flag bits in the Type column of the CustomAction table to specify return processing options. For a description of the options and the values, see Custom Action Return Processing Options. Execution Scheduling Options Include optional flag bits in the Type column of the CustomAction table to specify execution scheduling options. These options control the multiple execution of custom actions. For a description of the options, see Custom Action Execution Scheduling Options. In-Script Execution Options Include optional flag bits in the Type column of the CustomAction table to specify an in-script execution option. These options copy the action code into the execution, rollback, or commit script. For a description of the options, see Custom Action In-Script Execution Options. Return Values Custom actions that are executable files must return a value of 0 for success. The installer interprets any other return value as failure. To ignore return values, set the msidbCustomActionTypeContinue bit flag in the Type field of the CustomAction table. Remarks A custom action that launches an executable takes a command line, which commonly contains properties that are designated dynamically. If this is also a deferred execution custom action, the installer uses CreateProcessAsUser or CreateProcess to create the process when the custom action is invoked from the installation script. When a database table is exported, each stream is written as a separate file in the subfolder named after the table, using the primary key as the file name (Name column for the Binary table), with a default extension of ".ibd". The name should use the 8.3 format if the file system or version control system does not support long file names. The persistent archive file replaces the stream data with the file name used, so that the data can be located when the table is imported.

Custom Action Type 5


This custom action is written in JScript, such as ECMA 262. Windows Installer does not support JScript 1.0. For more information, see Scripts. Source The script is generated from a temporary binary stream. The Source field of the CustomAction table contains a key to the Binary table. The Data column in the Binary table contains the stream data. A separate stream is allocated for each row. New binary data can be inserted from a file by using MsiRecordSetStream followed by MsiViewModify to insert the record into the table. When the custom action is invoked, the stream data is copied to a temporary file, which is then processed according to the type of custom action. Type Value Include the following value in the Type column of the CustomAction table to specify the basic numeric type of 32bit custom action. Constants msidbCustomActionTypeJScript + msidbCustomActionTypeBinaryData Hexadecimal Decimal 0x05 5

Windows Installer may use 64-bit custom actions on 64-bit operating systems. A 64bit custom action based on scripts must include the msidbCustomActionType64BitScript bit in its numeric type. For information see 64bit Custom Actions. Include the following value in the Type column of the CustomAction table to specify the basic numeric type of a 64-bit custom action. Constants msidbCustomActionTypeJScript + msidbCustomActionTypeBinaryData + msidbCustomActionType64BitScript Hexadecimal Decimal 0x0001005 4101

Target The Target field of the CustomAction table contains an optional script function. Processing first sends the script for parsing and then calls the optional script function. Return Processing Options Include optional flag bits in the Type column of the CustomAction table to specify return processing options. For a description of the options and the values, see Custom Action Return Processing Options. Execution Scheduling Options Include optional flag bits in the Type column of the CustomAction table to specify execution scheduling options. These options control the multiple execution of custom actions. For a description of the options, see Custom Action Execution Scheduling Options. In-Script Execution Options Include optional flag bits in the Type column of the CustomAction table to specify an in-script execution option. These options copy the action code into the execution, rollback, or commit script. For a description of the options, see Custom Action In-Script Execution Options. Return Values Optional functions written in script must return one of the values described in Return Values of JScript and VBScript Custom Actions. Remarks A custom action that is written in JScript or VBScript requires the installation of Session Object. The installer attaches the Session object to the script with the name Session. Because the Session object may

not exist during an installation rollback, a deferred custom action written in script must use one of the methods or properties of the Session object described in the section Obtaining Context Information for Deferred Execution Custom Actions to retrieve its context. When a database table is exported, each stream is written as a separate file in the subfolder named after the table, using the primary key as the file name (Name column for the Binary table), with a default extension of ".ibd". The name should use the 8.3 file name format if the file system or version control system does not support long file names. The persistent archive file replaces the stream data with the file name used, so that the data can be located when the table is imported. Custom Action Type 6 This custom action is written in VBScript. For more information, see Scripts. Source The script is generated from a temporary binary stream. The Source field of the CustomAction table contains a key to the Binary table. The Data column in the Binary table contains the stream data. A separate stream is allocated for each row. New binary data can be inserted from a file by using MsiRecordSetStream followed by MsiViewModify to insert the record into the table. When the custom action is invoked, the stream data is copied to a temporary file, which is then processed depending upon the type of custom action. Type Value Include the following value in the Type column of the CustomAction table to specify the basic numeric type of a 32-bit custom action. Constants msidbCustomActionTypeVBScript + msidbCustomActionTypeBinaryData Hexadecimal Decimal 0x006 6

Windows Installer may use 64-bit custom actions on 64-bit operating systems. A 64bit custom action based on scripts must include the msidbCustomActionType64BitScript bit in its numeric type. For information see 64bit Custom Actions. Include the following value in the Type column of the CustomAction table to specify the basic numeric type of a 64-bit custom action. Constants msidbCustomActionTypeVBScript + msidbCustomActionTypeBinaryData + msidbCustomActionType64BitScript Hexadecimal Decimal 0x0001006 4102

Target The Target field of the CustomAction table contains an optional script function. Processing first sends the script for parsing and then calls the optional script function. Return Processing Options Include optional flag bits in the Type column of the CustomAction table to specify return processing options. For a description of the options and the values, see Custom Action Return Processing Options. Execution Scheduling Options Include optional flag bits in the Type column of the CustomAction table to specify execution scheduling options. These options control the multiple execution of custom actions. For a description of the options, see Custom Action Execution Scheduling Options. In-Script Execution

Options Include optional flag bits in the Type column of the CustomAction table to specify an in-script execution option. These options copy the action code into the execution, rollback, or commit script. For a description of the options, see Custom Action In-Script Execution Options. Return Values Optional functions written in script must return one of the values described in Return Values of JScript and VBScript Custom Actions. Remarks A custom action that is written in JScript or VBScript requires the installation of the Session Object. The installer attaches the Session object to the script with the name Session. Because the Session object may not exist during an installation rollback, a deferred custom action written in script must use one of the methods or properties of the Session object described in the section Obtaining Context Information for Deferred Execution Custom Actions to retrieve its context. When a database table is exported, each stream is written as a separate file in the subfolder named after the table, using the primary key as the file name (Name column for the Binary table), with a default extension of ".ibd". The name should use the 8.3 file name format if the file system or version control system does not support long file names. The persistent archive file replaces the stream data with the file name used, so that the data can be located when the table is imported. Custom Action Type 17 This custom action calls a dynamic link library (DLL) written in C or C++. Source The DLL is installed with the application during the current session. The Source field of the CustomAction table contains a key to the File table. The location of the custom action code is determined by the resolution of the target path for this file; therefore this custom action must be called after that file has been installed and before it is removed. Type Value Include the following value in the Type column of the CustomAction table to specify the basic numeric type. Constants msidbCustomActionTypeDll + msidbCustomActionTypeSourceFile Hexadecimal Decimal 0x011 17

Target The DLL is called through the entry point named in the Target field of the CustomAction table, passing a single argument that is the handle to the current install session. The entry point name specified in the table must match that exported from the DLL. Note that if the entry function is not specified by a .DEF file or by a /EXPORT: linker specification, the name may have a leading underscore and a "@4" suffix. The called function must specify the __stdcall calling convention. Return Processing Options Include optional flag bits in the Type column of the CustomAction table to specify return processing options. For a description of the options and the values, see Custom Action Return Processing Options. Execution Scheduling Options Include optional flag bits in the Type column of the CustomAction table to specify execution scheduling options. These options control the multiple execution of custom actions. For a description of the options, see Custom Action Execution Scheduling Options. In-Script Execution Options Include optional flag bits in the Type column of the CustomAction table to specify an in-

script execution option. These options copy the action code into the execution, rollback, or commit script. For a description of the options, see Custom Action InScript Execution Options. Return Values See Custom Action Return Values. Remarks A custom action that calls a dynamic-link library (DLL) requires a handle to the installation session. If this is also a deferred execution custom action, the session may no longer exist during execution of the installation script. For information on how a custom action of this type can obtain context information, see Obtaining Context Information for Deferred Execution Custom Actions. Custom actions execute in a separate thread, and may have limited access to the system. Custom actions that run asynchronously block the main thread at the termination of either the current sequence or the install session until they return. Custom actions that reference an installed file as their source, such as Custom Action Type 17 (DLL), must adhere to the following sequencing restrictions: The custom action must be sequenced after the CostFinalize action. This is so that the custom action can resolve the path needed to locate the DLL. If the source file is not already installed on the computer, deferred (in-script) custom actions of this type must be sequenced after the InstallFiles action. If the source file is not already installed on the computer, non-deferred custom actions of this type must be sequenced after the InstallFinalize action. Custom Action Type 18 This custom action calls an executable launched with a command line. Source The executable is generated from a file installed with the application. The Source field of the CustomAction table contains a key to the File table. The location of the custom action code is determined by the resolution of the target path for this file; therefore this custom action must be called after the file has been installed and before it is removed. Type Value Include the following value in the Type column of the CustomAction table to specify the basic numeric type. Constants msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile Hexadecimal Decimal 0x012 18

Target The Target column of the CustomAction table contains the command line string for the executable identified in the Source column. Return Processing Options Include optional flag bits in the Type column of the CustomAction table to specify return processing options. For a description of the options and the values, see Custom Action Return Processing Options. Execution Scheduling Options Include optional flag bits in the Type column of the CustomAction table to specify execution scheduling options. These options control the multiple execution of custom actions. For a description of the options, see Custom Action Execution Scheduling Options. In-Script Execution Options Include optional flag bits in the Type column of the CustomAction table to specify an in-script execution option. These options copy the action code into the execution, rollback, or commit script. For a description of the options, see Custom Action In-Script Execution Options. Return Values Custom actions that are executable files must return a value of 0 for success. The installer

interprets any other return value as failure. To ignore return values, set the msidbCustomActionTypeContinue bit flag in the Type field of the CustomAction table. Remarks A custom action that launches an executable takes a command line, which commonly contains properties that are designated dynamically. If this is also a deferred execution custom action, the installer uses CreateProcessAsUser or CreateProcess to create the process when the custom action is invoked from the installation script. Custom actions that reference an installed file as their source, such as Custom Action Type 18 (EXE), must adhere to the following sequencing restrictions: The custom action must be sequenced after the CostFinalize action. This is so that the custom action can resolve the path needed to locate the EXE. If the source file is not already installed on the computer, deferred (in-script) custom actions of this type must be sequenced after the InstallFiles action. If the source file is not already installed on the computer, non-deferred custom actions of this type must be sequenced after the InstallFinalize action. Custom Action Type 19 This custom action displays a specified error message, returns failure, and then terminates the installation. The error message displayed can be supplied as a string or as an index into the Error table. Source Leave the Source column of the CustomAction table blank. Type Value Include the following value in the Type column of the CustomAction table to specify the basic numeric type. Constants msidbCustomActionTypeTextData + msidbCustomActionTypeSourceFile Hexadecimal Decimal 0x013 19

Target The Target column of the CustomAction table contains a text string formatted using the functionality specified in MsiFormatRecord (without the numeric field specifiers). Parameters to be replaced are enclosed in square brackets, [], and may be properties, environment variables (% prefix), file paths (# prefix), or component directory paths ($ prefix). If after formatting the string evaluates to an integer, that integer is used as an index into the Error table to retrieve the message to display. If after formatting the string contains non-numeric characters, the string itself is displayed as the message. Return Processing Options The custom action does not use any options. Execution Scheduling Options The custom action does not use any options. In-Script Execution Options The custom action does not use any options. Return Values See Custom Action Return Values. Remarks For example, the custom actions CAError1, CAError2, CAError3, and CAError4 return these messages. CustomAction Table Action Type Source Target [Prop1] Installation failure due to Error2. 25000 [Prop2] CAError1 19 CAError2 19 CAError3 19 CAError4 19

Property Table Property Value Prop1 Prop2 "Installation failure due to Error1." "25100"

Error Table Code Message 25000 Installation failure due to Error3. 25100 Installation failure due to Error4. These custom actions return the following error messages:

You might also like