Using the InstallScript Engine as an External vs. Embedded UI Handler for InstallScript MSI Installations

InstallShield 2012 Spring

Project: This information applies to InstallScript MSI projects.

InstallScript MSI installations use two different installer engines:

The Windows Installer engine runs the standard Execute sequence of the .msi package. This is the sequence that typically modifies the target system.
The InstallScript engine serves as the custom user interface (UI) handler of the installation. It also executes the InstallScript code. The advantage of using the InstallScript engine for the UI is that it offers support for highly customized run-time dialogs.

Traditionally, Windows Installer has had support for only external custom UI handlers; therefore, InstallScript MSI installations have always required a Setup.exe setup launcher. The setup launcher serves as a bootstrap application that initiates the InstallScript engine to display the UI and run the InstallScript code, and the Windows Installer to run the Execute sequence of the .msi package.

Windows Installer 4.5 introduces support for embedded custom UI handlers. If the InstallScript engine is embedded within the .msi package, an InstallScript MSI installation does not require the Setup.exe setup launcher; end users can launch the installation by launching the .msi package. In this case, the .msi package contains the information that the Windows Installer needs to know about launching the InstallScript engine for the installation's UI.

Thus, InstallShield offers two different styles for the UI of InstallScript MSI installations:

Traditional style (requires a Setup.exe setup launcher)—This style lets you use the InstallScript engine as an external UI handler for your InstallScript MSI installation. This is the default style.
New style (requires Windows Installer 4.5 on the target machine)—This style lets you use the InstallScript engine as an embedded UI handler for your InstallScript MSI installation. With this style, InstallShield embeds the InstallScript engine within the .msi package. Note that this option has some limitations.

The following sections provide detailed information about these two styles; review this information to determine which style would best meet your requirements.

Traditional Style (InstallScript Engine as an External UI Handler)

The general flow in a traditional-style InstallScript MSI package during a first-time installation is as follows:

1. The InstallScript engine opens the .msi package.
2. All actions in the Installation UI sequence are run with the exception of the ExecuteAction. The actions are run in ascending sequence order.
3. The InstallScript engine performs its own internal component costing to determine the space required for all features and components in the installation.
4. The InstallScript engine launches the compiled script contained in ISSetup.dll. The event sequence for the events that are run before the .msi package installation is as follows:
a. OnBegin
b. OnXxxUIBefore (where Xxx is First, Maint, Admin, Patch, Resume, etc.)
c. OnGeneratingMsiScript
d. OnMoving
e. OnFeaturesInstalling (Any feature installing and uninstalling events are run at this point.)
f. OnInstallFilesActionBefore
g. OnGeneratedMsiScript
5. The InstallScript engine launches the .msi package installation through MsiInstallProduct. The following factors determine the command line that the InstallScript engine passes through MsiInstallProduct: installation mode (for example, first-time installation, maintenance mode, minor upgrade, patch), internal feature selections, and current property values.
6. If the .msi package installation is successful, the InstallScript engine writes the secondary uninstall key (InstallShield_{ProductCode}) to the machine and then launches the following events:
a. OnInstallFilesActionAfter
b. OnFeaturesInstalled (Any feature installed and uninstalled events are run at this point.)
c. OnMoved
d. OnXxxUIAfter (where Xxx is First, Maint, Admin, Patch, Resume, etc.)
e. OnEnd
7. After the script has completed, the InstallScript engine writes the InstallScript log to the machine.
8. The InstallScript engine shuts down.

New Style (InstallScript Engine as an Embedded UI Handler)

The InstallScript MSI embedded UI support attempts to follow the same general flow as traditional-style InstallScript MSI installation. However, there are certain portions of the flow that do not occur or are unnecessary. The general flow in a new-style InstallScript MSI package during a first-time installation is as follows:

1. The .msi package is launched directly or by Setup.exe (which then launches Msiexec.exe, which is the same behavior for a Basic MSI installation).
2. The Windows Installer engine extracts all files that are in the MsiEmbeddedUI table and calls the initialize embedded UI function in the DLL that contains the embedded UI handler attribute. (In the InstallScript MSI case, this is ISSetup.dll).
3. The InstallScript engine initializes and manually launches the ISSetupFilesExtract action if it is present and its condition in the InstallUISequence evaluates to true.
4. The InstallScript engine performs manual resolution of all entries in the Directory table.
5. The InstallScript engine performs its own internal component costing to determine the space required for all features and components in the installation.
6. The InstallScript engine launches the compiled script contained in ISSetup.dll. The event sequence for the events that are run before the .msi package installation is as follows:
a. OnBegin
b. OnXxxUIBefore (where Xxx is First, Maint, Admin, Patch, Resume, etc.)
c. OnGeneratingMsiScript
d. OnMoving
e. OnFeaturesInstalling (Any feature installing and uninstalling events are run at this point.)
f. OnInstallFilesActionBefore
g. OnGeneratedMsiScript
7. The InstallScript engine returns control to the Windows Installer engine, which then begins running the installation's Execute sequence.
8. If the .msi package installation is successful, the Windows Installer engine calls back into ISSetup.dll. ISSetup.dll then launches the following events:
a. OnInstallFilesActionAfter
b. OnFeaturesInstalled (Any feature installed and uninstalled events are run at this point.)
c. OnMoved
d. OnXxxUIAfter (where Xxx is First, Maint, Admin, Patch, Resume, etc.)
e. OnEnd
9. The InstallScript engine shuts down and returns control to the Windows Installer.

For the new-style InstallScript MSI installations, the Install UI sequence is not run. If any custom actions are sequenced in the Install UI sequence, they will not run, similar to how such actions would not run in a Basic MSI that is launched with /qb or /qn.

The InstallScript engine does not log any changes that are made to the system from InstallScript events.

Most command-line parameters that are supported by traditional-style InstallScript MSI installations are also supported for new-style InstallScript MSI installations. If an end user launches the .msi package directly, these parameters can be passed through the ISSCRIPTCMDLINE property.

Limitations with the Traditional Style (InstallScript Engine as an External UI Handler)

Uninstallable Patch Support

The traditional style does not have support for creating uninstallable patches.

Limitations and Known Issues with the New Style (InstallScript Engine as an Embedded UI Handler)

If you are considering the new style, note the following details.

Windows Installer 4.5 Requirement

The new style requires that Windows Installer 4.5 be present on the target system. You can add InstallShield prerequisites for Windows Installer 4.5 to your project so that Windows Installer 4.5 is installed if it is not present. If you include these InstallShield prerequisites in your installation, you need to use a Setup.exe setup launcher. For more information, see Adding Windows Installer Redistributables to Projects. Note that Windows Installer 4.5 cannot be installed on some of the early versions of Windows.

If Windows Installer 4.5 is not installed on a target system at run time, and the installation is launched with Setup.exe, the setup launcher displays error 1713 and indicates that the installation requires Windows Installer 4.5 or later in order to run. The installation aborts after the end user dismisses this error message. If the .msi package is launched directly, the installation displays an error indicating that the package needs to be launched from the Setup.exe file.

Upgrade and Patch Support

InstallShield does not include any built-in support for creating an upgrade that uses the new style if the upgrade updates a product that was installed with the traditional style. Therefore, if you use the traditional style to build a release of your product and then you later create an upgrade, consider using the traditional style again for the upgrade. This applies to all types of upgrades (major upgrades, minor upgrades, and small updates) that are packaged as full-installations or as patches.

Note that if the previous setups that a patch is targeting use the traditional style, the patch should also use the traditional style. Also note that a QuickPatch project maintains the UI style from the original installation. Therefore, if the original installation used the traditional style, the QuickPatch package also uses the traditional style. If the original installation used the new style, the QuickPatch package also uses the new style.

As a workaround for the major upgrade scenario, you could consider having your new-style major-upgrade installation read the uninstall string of the earlier product from the registry, and launching it with the InstallScript function LaunchApplication to uninstall the earlier version of your product before installing the new version. Note that you may need to set LAAW_SHELLEXECUTEVERB> to runas before using LaunchApplication in your script.

MsiDoAction

Attempting to call the MsiDoAction function from one of the events that are run before the .msi package installation returns an error. This error occurs because of the handle that the Windows Installer passes to the InstallScript engine. The handle does not support running standard or custom actions in the .msi package. This function can be called from InstallScript custom actions if needed.

MsiGetTargetPath and MsiSetTargetPath

The Windows Installer MsiGetTargetPath and MsiSetTargetPath functions do not work correctly in the new style if they are in event-driven script. These functions rely on the Directory Manager having been initialized by the Windows Installer costing actions. In new-style InstallScript MSI installations, Windows Installer costing is not performed. Thus, MsiGetTargetPath fails to return any path information, and MsiSetTargetPath fails to set the requested target path. In both cases, Windows Installer logs messages in a verbose log if either of these functions are called.

To update installation paths, use FeatureSetTarget.

Note that MsiGetTargetPath and MsiSetTargetPath can be called through InstallScript custom actions that are sequenced after CostFinalize in the Installation Execute sequence.

FeatureTransferData and ComponentTransferData

The behavior of the InstallScript functions FeatureTransferData and ComponentTransferData is undefined for the new style of InstallScript MSI installations and should not be used.

program...endprogram

New-style InstallScript MSI installations cannot use procedural scripts (that is, those with a program...endprogram block). The program function is not called in this case. An event-driven script should be used to customize the behavior of the installation.

/uninst

New-style InstallScript MSI installations do not support the /uninst command-line parameter.

BATCH_INSTALL

Attempting to reboot by setting the BATCH_INSTALL variable does not work correctly. To perform a reboot, use the ScheduleReboot action or the REBOOT property.

Reboot Support

Reboots for new-style InstallScript MSI installations are handled in the same manner as they are handled for Basic MSI installations—not as they are handled for InstallScript-based installations (where the installation resumes after the restart and the OnRebooted event handler is called).

New-style InstallScript MSI installations should be authored similarly to Basic MSI installations to handle reboots; the installation does not run after a scheduled reboot occurs, and the OnRebooted event handler is not called.

Msiexec.exe /x (for Uninstallation)

If an end user tries to uninstall the product through the command line using the statement Msiexec.exe /x {ProductCode}, the uninstallation may be successful. However, the Windows Installer displays an error dialog near the end of the uninstallation. The error dialog indicates that the Windows Installer service could not be accessed.

To perform an uninstallation from the command line, the current recommended method is to use one of the following:

msiexec.exe /i {ProductCode} REMOVE=ALL

msiexec.exe /x {ProductCode} /qn

Neither of these examples triggers the Windows Installer error.

Recommendations

For new-style InstallScript MSI installations, the UI functionality may be run without administrator privileges. Therefore, the following points are recommended (and, in general, also apply to all Windows Installer–based installations):

Do not assume that administrator privileges will be available from any InstallScript events.
Any system changes that need to be made should be done with custom actions in the Installation Execute sequence. InstallScript custom actions can be used. To ensure that sufficient privileges are available, custom actions should have an in-script execution setting of deferred in system context.
Custom actions that modify the system should have corresponding rollback actions that restore the system to its earlier state if the installation fails.
Custom actions that modify the system should also have corresponding actions that run during uninstallation to remove the installed items from the system.
If changes are made to the system from InstallScript events, the changes are not logged by the InstallScript engine and would need additional script code to clean up these resources during uninstallation.

Using InstallScript to Differentiate Between the Two Styles at Run Time

You can use the INSTALLSCRIPTMSIEEUI variable to write a single script that produces different run-time behavior for the different UI styles. To learn more, see INSTALLSCRIPTMSIEEUI.

See Also