For some time I've wondered why I am not able to use MSI properties in deferred custom actions. It took me a lot of effort to find the solution. I do like to share knowledge so I wrote this up. Hope it helps you as you customize your MSIs.
A Basic MSI installation program uses sequences of actions to determine the dialog boxes and operations the installation program should display and perform.
There are two sequences used by a typical installation program:
- User Interface sequence: The User Interface sequence displays dialog boxes and queries the target system, but does not make any system changes.
- Execute sequence: The Execute sequence performs system changes, but does not display a user interface.
Similar to how we use variables in a programming language we can use different properties in Windows Installer Technology. It has many Predefined Custom Actions, and Installation author or Scripter can define custom properties to store any extra data needed at run time. A property can, for example, be set by the user in a dialog box, and then later be written to the registry.
Property names are case sensitive. Two classes of MSI properties which we oftenly use.
- Public properties
- Private properties
Public Properties have names containing only uppercase letters (examples are USERNAME and INSTALLDIR, although INSTALLDIR is actually a directory Property but can use as PUBLIC Property).
Private Properties, whose names contain at least one lowercase letter (as in AdminUser or LogonUser).
The values of public properties can be set at the command line, and their values are preserved when execution switches from the User Interface sequence to the Execute sequence.
Private properties cannot have their values set at the command line, and are reset to their default values when execution switches from the User Interface sequence to the Execute sequence.
During installation, the Execute sequence runs in two stages: immediate mode and deferred mode. Immediate mode walks through the actions in the Execute sequence, generating an internal, hidden installation script. This script contains, for example, instructions for what files, registry data, shortcuts to install. Immediate mode does not touch the target system. Note that the User Interface sequence runs only in immediate mode.
The second stage of the Execute sequence, deferred mode, carries out the system changes described by this internal installation script. (deferred mode is performed only for actions between the built-in actions InstallInitialize and InstallFinalize.) During deferred execution, MSI property values are fixed and cannot be changed. Moreover, the values of only a handful of MSI properties can explicitly be read during deferred execution.
During immediate execution, a VBScript custom action can read the value of an MSI property, using the Property of the Session object.
- Getting Property Values in Custom Actions
- Get a property value during immediate mode
- Msgbox Testusername
- same but VBscript Custom Action can not used in the Deferred custom action.
As mentioned above, however, getting the value of an MSI property during deferred execution is somewhat more difficult, as deferred actions have access to only a very few built-in properties: ProductCode, UserSID, and CustomActionData.
For example, a deferred launch-an-EXE action that uses "[INSTALLDIR]Help.txt" as its argument will have the INSTALLDIR property resolved during immediate mode and fixed during deferred mode. It is only custom actions that explicitly read a property value using Session.Property
CustomActionData, that is used to read a property value in a script during deferred mode.
Here you need to use:
This will be your script and will be called in deferred mode.
Use the following methods:
- Click on the MSI Script tab and select installation mode as All Custom Actions, then select the option of Call VBScript From Installation.
- In the Call VBScript from Installation menu, under Details tab give a suitable Custom Action Name (Eg:EDIT_FILE), then browse and associate the VBScript (ie .vbs file) with the Script File option.
- Then under the location tab Uncheck No Sequence option and select Sequence as Normal Execute Immediate/Deferred and add the EDIT_FILE custom action before the InstallFinalize option and position it with the help of Move up or Move down options. Then put the condition as NOT REMOVE~="ALL" (This ensures that the custom action is called only during application installation and repair not during un-installation)
- Under the Properties Tab select In-Script Options as Deferred Execution-System Context and select the Processing option as Synchronous, Ignore exit code and click OK.
- Now set property for EDIT_FILE custom action (Now this Property Name should be Match with your VBScript Custom Action Name where CustomActionData is used)
- In Set Property, under details tab give a suitable name for the Custom Action Name and set property as EDIT_FILE .In Property Value we pass the following parameters [INSTALLDIR]
- Place it after InstallInitialize.
- Now you will be able to see the Public Property in deffered execution.