Microsoft Windows Installer SDK
Deferred Custom Action
When Windows Installer processes the installation script, it creates a rollback script at the same time. In addition to the rollback script, the installer saves a copy of each file that it deletes during the installation. These files are kept in a hidden system directory. Once the installation is complete, the rollback script and the saved files are deleted. If an installation is unsuccessful, the installer attempts to undo the changes made during the installation and restore the computer to its original state.
Deferred Execution Custom Actions
The purpose of a delayed execution custom action is to delay the execution of a system change until the installation script is executed. This is different from a regular custom action or a default action, where the installer executes the action immediately when it occurs in a sequence table or when MsiDoAction is called.
A delayed execution custom action allows a package author to specify system operations at a specific point within the execution of the installation script. The installer does not perform a custom deferred execution action at the time the installation sequence is processed. Instead, the installer writes the custom action to the installation script. Custom deferred execution actions must come after InstallInitialize and before InstallFinalize in the action sequence.
Custom actions that directly modify the system or issue commands to other system services cannot always be undone by a rollback. A custom rollback action is an action that the installer performs only during an installation rollback, and its purpose is to undo a custom action that made changes to the system.
Definition of a CustomAction (type definition)

In the MSDN, the field Type
is explained like this: "A field of flag bits (another word for Bitmask) specifying the basic type of custom action and options."
Column | Type | Key | Nullable |
---|---|---|---|
Action | Identifier | Y | N |
Type |
Integer |
N | N |
Source | CustomSource | N | Y |
Target | Formatted | N | Y |
ExtendedType | DoubleInteger | N | Y |
So for my CustomAction I first have to determine the base type. In the example it would be the value 34
(EXE file having a path referencing a directory). A Deferred CustomAction is an In-Script Execution Option and because it should run in the system context, we choose the value 3072
(msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate). We want the CustomActions to run synchronously and not abort the entire installation even if an error occurs. We add the value 64
(Custom Action Return Processing Options). Add these three determined values together 34 + 3072 + 64 = 3170
- et voilà.
Custom Action Sources
Custom action source | Associated custom action types |
---|---|
Custom action stored in the Binary table. | Custom Action Type 1, Custom Action Type 2, Custom Action Type 5, Custom Action Type 6 |
Custom action copied during installation. | Custom Action Type 17, Custom Action Type 18, Custom Action Type 21, Custom Action Type 22 |
Custom action referencing a directory. | Custom Action Type 34 |
Custom action referencing a property. | Custom Action Type 50, Custom Action Type 53, Custom Action Type 54 |
Custom action stored as literal script code in database table. | Custom Action Type 37, Custom Action Type 38 |
Custom action displaying an error message. | Custom Action Type 19 |
The basic types of custom actions
Custom action type | Type Source | Target |
---|---|---|
1 DLL file stored in a Binary table stream. |
Key to Binary table. | DLL entry point. |
2 EXE file stored in a Binary table stream. |
Key to Binary table. | Command-line string. |
5 JScript file stored in a Binary table stream. |
Key to Binary table. | An optional JScript function that can be called. |
6 VBScript file stored in a Binary table stream. |
Key to Binary table. | An optional VBScript function that can be called. |
17 DLL file that is installed with a product. |
Key to File table. | DLL entry point. |
18 EXE file that is installed with a product. |
Key to File table. | Command-line string. |
19 Displays a specified error message and returns failure, terminating the installation. |
Blank | Formatted text string. The literal message or an index into the Error table. |
21 JScript file that is installed with a product. |
Key to File table. | An optional JScript function that can be called. |
22 VBScript file that is installed with a product. |
Key to File table. | An optional VBScript function that can be called. |
34 EXE file having a path referencing a directory. |
Key to Directory table. This is the working directory for execution. | The Target column is formatted and contains the full path and name of the executable file followed by optional arguments. |
35 Directory set with formatted text. |
A key to the Directory table. The designated directory is set by the formatted string in the Target field. | A formatted text string. |
37 JScript text stored in this sequence table. |
Null | A string of JScript code. |
38 VBScript text stored in this sequence table. |
Null | A string of VBScript code. |
50 EXE file having a path specified by a property value. |
Property name or key to Property table. | Command-line string. |
51 Property set with formatted text. |
Property name or key to the Property table. This property is set by the formatted string in the Target field. | A formatted text string. |
53 JScript text specified by a property value. |
Property name or key to Property table. | An optional JScript function that can be called. |
54 VBScript text specified by a property value. |
Property name or key to Property table. | An optional VBScript function that can be called. |
Custom Action In-Script Execution Options
You can use the following flags to specify the in-script execution of custom actions. These options copy the action code to the execution, rollback, or commit script. To set an option, add the value in this table to the value in the Type field of the CustomAction table.Term | Description |
---|---|
(none) | Hexadecimal: 0x00000000 Decimal: 0 Immediate execution. |
msidbCustomActionTypeInScript | Hexadecimal: 0x00000400 Decimal: 1024 Queues for execution at scheduled point within script. This flag designates that this is a deferred execution custom action. |
msidbCustomActionTypeInScript + msidbCustomActionTypeRollback |
Hexadecimal: 0x00000400 + 0x00000100 Decimal: 1280 Queues for execution at scheduled point within script. Executes only upon an installation rollback. This flag designates that this is a rollback custom action. |
msidbCustomActionTypeInScript + msidbCustomActionTypeCommit |
Hexadecimal: 0x00000400 + 0x00000200 Decimal: 1536 Queues for execution at scheduled point within script. Executes only upon install commit. This flag designates that this is a commit custom action. |
msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate |
Hexadecimal: 0x00000400 + 0x00000800 Decimal: 3072 Queues for execution at scheduled point within script. Executes with no user impersonation. Runs in system context. |
msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate + msidbCustomActionTypeRollback |
Hexadecimal: 0x00000400 + 0x00000800 + 0x00000100 Decimal: 3328 Queues for execution at scheduled point within script. Executes with no user impersonation. Runs in system context. This flag combination designates that this is a rollback custom action. |
msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate + msidbCustomActionTypeCommit |
Hexadecimal: 0x00000400 + 0x00000800 + 0x00000200 Decimal: 3584 Queues for execution at scheduled point within script. Executes with no user impersonation. Runs in system context. This flag combination designates that this is a commit custom action. |
msidbCustomActionTypeTSAware + msidbCustomActionTypeInScript |
Hexadecimal: 0x00000400 + 0x00004000 Decimal: 17408 Queues for execution at the scheduled point within script. Executes with user impersonation. Runs with user impersonation during per-machine installs on a server running the Terminal Server role service. Normal deferred execution custom actions, without this attribute, run with no user impersonation on a terminal server during per-machine installations. This attribute has no effect if the action also has the msidbCustomActionTypeNoImpersonate attribute. |
msidbCustomActionTypeTSAware + msidbCustomActionTypeInScript + msidbCustomActionTypeRollback |
Hexadecimal: 0x00000400 + 0x00004000 + 0x00000100 Decimal: 17664 Queues for execution at the scheduled point within script. Run only upon an installation rollback. Execute with user impersonation. Runs with user impersonation during per-machine installs on a terminal server. |
msidbCustomActionTypeTSAware + msidbCustomActionTypeInScript + msidbCustomActionTypeCommit |
Hexadecimal: 0x00000400 + 0x00004000 + 0x00000200 Decimal: 17920 Queues for execution at the scheduled point within script. Runs only upon an install commit. Executes with user impersonation. Runs with user impersonation during per-machine installs on a terminal server. |
Custom Action Return Processing Options
Constant | Description |
---|---|
(none) | Hexadecimal: 0x00000000 Decimal: 0 A synchronous execution that fails if the exit code is not 0 (zero). If the flag msidbCustomActionTypeContinue is not set, then the custom action must return one of the return values that is described in Custom Action Return Values. |
msidbCustomActionTypeContinue | Hexadecimal: 0x00000040 Decimal: +64 A synchronous execution that ignores exit code and continues. |
msidbCustomActionTypeAsync | Hexadecimal: 0x00000080 Decimal: +128 An asynchronous execution that waits for exit code at the end of the sequence. This option cannot be used with Concurrent Installations, Rollback Custom Actions, or Script Custom Actions. |
msidbCustomActionTypeAsync + msidbCustomActionTypeContinue | Hexadecimal: 0x00000040 + 0x00000080 Decimal: +192 An asynchronous execution that does not wait for completion. Execution continues after Windows Installer terminates. This option can only be used with the EXE type custom actions that is, executable files. All other types of custom actions can be asynchronous only within the install session, and must end for the installation to terminate. This option cannot be used with Concurrent Installations. |
Custom Action Hidden Target Option
Constant | Description |
---|---|
(none) |
Hexadecimal: 0x00000000 Decimal: 0 The installer may write the value in the Target column of the CustomAction table into the log file. |
msidbCustomActionTypeHideTarget |
Hexadecimal: 0x2000 Decimal: 8192 The installer is prevented from writing the value in the Target column of the CustomAction table into the log file. The CustomActionData property is also not logged when the installer executes the custom action. Because the installer sets the value of CustomActionData from a property with the same name as the custom action, that property must be listed in the MsiHiddenProperties Property to prevent its value from appearing in the log. |
Custom Action Return Values
Return value | Description |
---|---|
ERROR_FUNCTION_NOT_CALLED | Action not executed. |
ERROR_SUCCESS | Completed actions successfully. |
ERROR_INSTALL_USEREXIT | User terminated prematurely. |
ERROR_INSTALL_FAILURE | Unrecoverable error occurred. |
ERROR_NO_MORE_ITEMS | Skip remaining actions, not an error. |
Also note that Windows Installer translates the return values from all actions when it writes the return value to the log file. For example, if the return value of the action appears as 1 in the log file, it means that the action returns ERROR_SUCCESS.