Shop

InstallShield
Advanced Installer
AdminStudio
more / weitere

InstallShield und AdminStudio Schulungen

weitere Infos

Windows Installer Custom Actions

DLL and InstallScript Custom Actions: You can find many InstallScript code snippets and extension DLLs for various tasks under the InstallScript Samples menu. Many of them can be used in Windows Installer as custom actions, however may require some modifications.

Decode the CustomActionData Property in InstallScript

A simple InstallScript function for easily decoding the CustomActionData property. Useful for deferred execution custom actions written in InstallScript.

Originally created in 2006, the code has been updated to also work with InstallShield 2012.

ZIP CustomActionDataRul.zip    Written by Christopher Painter
File size: 1.078 bytes   Last update: 2012-03-11

Register Microsoft Enterprise Library

This Custom Action is for use within MSI packages in order to install the output assemblies of the new Microsoft Enterprise Library correctly. This Custom Action is not dependant on installutil, it performs the necessary steps itself. Just add the Custom Action to any project using the new Enterprise Library and the correct components (the same ones as registered through use of 'InstallServices.bat') will be installed / uninstalled as appropriate.

WWW Download from Martijn's Blog

Sample Custom Action DLL Written in C++

This article on The Code Project will step you through adding a custom action DLL to a Windows Installer setup.

WWW MSI Custom Action DLL at The Code Project

Check if License Text was Completely Viewed

This C++ file includes the source code for a custom action that finds the License Agreement dialog of a setup and checks whether the text in the scrollable area is scrolled down to the end.

ZIP IsLicenseViewed.zip    Written by Kallely L Sajan
File size: 1.211 bytes   Last update: 2003-08-13

Darwin Transform and Its Application in Windows Installer Custom Actions

In some cases, using Windows Installer API functions does not provide information about certain specific elements of a Windows Installer package.

Let us consider the following scenario.

During the initial installation, the setup disables some features (setting their install level to 0), if certain conditions are not satisfied. Now, if the user updates the system configuration and reinstalls or upgrades the installed .msi package, some or all of those hidden features need to be selected by default. At the same time, those visible features, which were deselected by the user, should keep their "absent" state.

Thus, there is a need for a method to distinguish between the deselected and disabled (install level = 0) features, so that the setup could perform required manipulations during reinstallation or upgrade. It seems, however, that Windows Installer API functions do not allow for making such a distinction.

Yet, it is indeed possible to obtain the required information by taking a different approach. The sample below illustrates the corresponding techniques based on analyzing product code and upgrade code keys from the registry database and applying the Darwin Transform to get the solution to the problem at hand.

Indeed, analysis of some installer registry keys provides a lot of additional valuable information about the installation package structure and configuration. For instance, it is possible to get information about the feature states (drawing thereby the distinction between deselected and disabled features), distinguish between parent and child features, and so on. This information can be obtained without using MSI API functions, but merely through analyzing the Installer\Features\{Packed ProductCode GUID} registry key of the installed package.

There are several information types that Windows Installer writes into the registry, but for further discussion it is important to distinguish between a standard and packed GUID (these and other information types are discussed in various sources; a very good summary can be found, for instance, in chapter 7 of "Administrator's Introduction to Application Repackaging and Software Deployment using Windows Installer" by Bob Baker and Robert Dickau).

A standard GUID requires 38 characters and contains 5 groups of hexadecimal characters separated by dashes. The valid format for a standard GUID is:

{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}

where X is a hex digit (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F).

A packed GUID is an alternative representation that allows Windows Installer to reduce the space in the registry database when storing a GUID. A packed GUID requires only 32 characters. Its valid format is:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

where X is a hex digit.

A packed GUID can be obtained by applying a transform to a standard GUID. This transform performs the following operations:

I have coined the name Darwin Transform for this conversion procedure, since its primary use is to construct a well-known Darwin Descriptor, which is a combination of the product code GUID, a feature name, and a component code GUID.

To uncover some concealed internals of the installed .msi package, one needs to correctly interpret the content of the Packed ProductCode GUID key, which can be obtained from the Packed UpgradeCode GUID registry key. Application of the Darwin transform allows to obtain the required information about the package features in the reinstallation and upgrade scenarios.

The sample FeatureConfigCheck Windows Installer package has three features. To illustrate the suggested method, the package INSTALLLEVEL was set by default to 100, whereas the install level of the first, second, and third feature was set to 0, 300, and 1, respectively. For simplicity sake, I have dealt in this sample only with the HKLM\Software\Classes\Installer keys, and have not operated with security identifiers.

The TESTFEATURESTATES custom action is fired when running the setup in maintenance mode or in the upgrade scenario.

The InstallScript file contains the UpdateFeatureStates entry-point function, which is called by the TESTFEATURESTATES custom action, and several private functions, called by the entry-point function.

The ObtainDarwinUpgradeCode private function obtains the packed Upgrade Code GUID GUID by applying the Darwin Transform to the standard Upgrade Code.

The packed Upgrade Code GUID key is used by the RetrieveDarwinProductCode private function to retrieve the packed Product Code GUID.

The ControlFeatures private function verifies the feature presence in a local database and changes the installation states of the deselected and disabled features.

Package reinstallation or upgrade will then display the information about the feature states and set their state to INSTALLSTATE_LOCAL.

ZIP FeatureConfigCheck.zip    Written by Valery Atlas
File size: 1.858.581 bytes   Last update: 2003-10-03

Enable Setup to Take Focus

Sometimes your setup program may lose focus, e.g. because it is launching another program. To regain focus you can call the SetForegroundWindow function in the Windows API.   However on Windows 98/Me and Windows 2000 or later the system restricts which processes can set the foreground window, and typically your setup program won't meet the criteria.

Here are two solutions to this problem:

Temporarily disable the restrictions for SetForegroundWindow

Other processes than the current forground process are prevented from using SetForegroundWindow for a certain amount of time after the last user input. You can set this timeout to 0 to allow any process to put itself at the top of the Z order at any time. Note that this is a global setting, so other processes can grab the foreground window, too. Also you should restore the previous timeout value after your setup has finished.

To use this method in InstallScript, add these defines to the top of your setup.rul:

#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
#define SPIF_UPDATEINIFILE 0x0001
#define SPIF_SENDWININICHANGE 0x0002

Then, at the beginning of the setup.rul add this:

SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lockTime, 0);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 
                     SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);

Then, at the very end of the setup.rul add this:

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, lockTime, 
                     SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);

You should also add this last statement at any location that would terminate your setup.

Written by David Boyd
Last update: 2001-08-16

Grant setup the right to set the foreground window

A process can set the foreground window if it currently is the foreground process or if it was started by the foreground process. Here is a program that will launch your setup and grant the launched program the right to set the foreground window to put itself at the top of the Z order. This right is granted only to your setup program, not to other processes.

ZIP AllowSetForeground.zip    Written by Joe Nathanson
File size: 14.044 bytes   Last update: 2001-06-27

Attach Database with MSDE

Here is a VBscript that based on a bunch of properties will start the sql service, attach a database of your choice, create a user and add them to the database as a db_owner. Its fully modifiable and you can easily see where you could add extra permissions etc. It also works with Instances.

ZIP AttachDB.zip    Written by James Hancock
File size: 3.119 bytes   Last update: 2000-06-22

List SQL Servers

This VB Script snippet shows how to use SQLDMO to get a list of all SQL Servers that can be used to build a list box.

ZIP ListSQLServers.zip    Written by Steve Phillips
File size: 438 bytes   Last update: 2001-07-09

Calling a Visual Basic ActiveX DLL as Custom Action

To use an ActiveX DLL in a custom action, you must peform four steps:

  1. Resolve the path to the ActiveX DLL
  2. Register the ActiveX DLL
  3. Use the ActiveX DLL
  4. Unregister the ActiveX DLL

This Word document explains these steps in detail.

ZIP ActiveX_CA.zip    Written by Gene Webb
File size: 60.909 bytes   Last update: 2000-03-11

Create Virtual Directory in IIS

The following is a script to create an IIS virtual directory, and set IIS properties for the web. Also included is a script to enable IIS Out-of-process components (that is, allows ASP pages to call ActiveX EXE components that run in a separate process). The script includes a workaround for a known bug in IIS4.

If there are any errors during execution of the script, it displays a relatively detailed error message in a message box, and also returns ERROR_INSTALL_FAILURE to Windows Installer. (Note that the message boxe will be a problem for an unattended installation. You may want to substitute Windows Installer log messages for the message boxes.)
Comments in the VBS source code explain how to create custom actions using the script files and how to pass information to and from the scripts using Windows Installer properties. It may serve as an example for creating other scripts.
The sections marked "EXAMPLE USAGE:" in each file (typically where Session properties are read and written) need to be modified for each individual's (or group's) use of the script file.

ZIP iis.zip    Written by Philip Dickerson
File size: 6.948 bytes   Last update: 2002-03-14

Detect File System

A custom action written in VB Script that will detect whether a given directory is on a FAT or a NTFS partition.

If there are any errors during execution of the script, it displays a relatively detailed error message in a message box, and also returns ERROR_INSTALL_FAILURE to Windows Installer. (Note that the message boxe will be a problem for an unattended installation. You may want to substitute Windows Installer log messages for the message boxes.)
Comments in the VBS source code explain how to create custom actions using the script files and how to pass information to and from the scripts using Windows Installer properties. It may serve as an example for creating other scripts.
The sections marked "EXAMPLE USAGE:" in each file (typically where Session properties are read and written) need to be modified for each individual's (or group's) use of the script file.

ZIP CheckFileSystem.zip    Written by Philip Dickerson
File size: 3.331 bytes   Last update: 2002-03-13

File Browse Dialog

This package includes a DLL and instructions how to display a "Browse for File" dialog.

Fix: If a user typed something into the edit box before clicking Browse (to launch the custom action) the edit box did not update upon returning from the browse function.

ZIP BrowseForFile.zip    Written by Jeff Briggs
File size: 503.067 bytes   Last update: 2004-03-05

Get Short Name Equivalent for Long Path

If you need to find the short name equivalent of the installation directory (or some other path), this VB Script will achieve this.
Note that if you want the short name equivalent of the installation directory (or any other directory created during the install), this script must be executed late enough in the sequence that the directories have actually been created - this typically means after the "ExecuteAction" action.

If there are any errors during execution of the script, it displays a relatively detailed error message in a message box, and also returns ERROR_INSTALL_FAILURE to Windows Installer. (Note that the message boxe will be a problem for an unattended installation. You may want to substitute Windows Installer log messages for the message boxes.)
Comments in the VBS source code explain how to create custom actions using the script files and how to pass information to and from the scripts using Windows Installer properties. It may serve as an example for creating other scripts.
The sections marked "EXAMPLE USAGE:" in each file (typically where Session properties are read and written) need to be modified for each individual's (or group's) use of the script file.

ZIP GetShortPaths.zip    Written by Philip Dickerson
File size: 3.826 bytes   Last update: 2002-03-13

MTS Management

A set of custom actions to create and delete MTS packages, install components into a created MTS package, and set the MTS transaction timeout. The scripts are written in VBS.

If there are any errors during execution of the script, it displays a relatively detailed error message in a message box, and also returns ERROR_INSTALL_FAILURE to Windows Installer. (Note that the message boxe will be a problem for an unattended installation. You may want to substitute Windows Installer log messages for the message boxes.)
Comments in the VBS source code explain how to create custom actions using the script files and how to pass information to and from the scripts using Windows Installer properties. It may serve as an example for creating other scripts.
The sections marked "EXAMPLE USAGE:" in each file (typically where Session properties are read and written) need to be modified for each individual's (or group's) use of the script file.

ZIP MTSPackage.zip    Written by Philip Dickerson
File size: 7.939 bytes   Last update: 2002-03-14

Register TLB File Using VBScript

This VBScript custom action can register/unregister a typelib file on the system. It makes use of 2 properties, one of which needs to be set before the action is called (typelib filename). It uses the TLI object which is part of the Windows operating system (at least 2000 and greater).

  1. Set VAR_TYPELIB_FILE to the name of the typelib file (including path)
  2. Call the RegisterTypeLib function to register and UnRegisterTypeLib to unregister the type library. This can be done either by inserting it in the sequence table or calling it manually using DoAction.
  3. Check the result by referring to the property VAR_CUSTOM_ACTION_RESULT.

ZIP RegisterTypeLibVBS.zip    Written by Corey Frost
File size: 773 bytes   Last update: 2002-04-14

Streaming a File From the Binary Table

Enhanced Version

The purpose of this custom action is to stream a user specified file from the binary table and replace any properties with their values before writing it out to disk. For example, if you had a file with the contents:
    This is a [MYPROPERTY] test.
and MYPROPERTY was equal to "COOL" the streamed file would look like:
    This is a COOL test.
The user can also specify the path and filename to store the output file and (unlike the classic version below) more than one file can be stored in the binary table.
The maximum file size is about 4kB because of an apparent limit in the MsiFormatRecord API.
Usage directions can be found in the script. Written in InstallScript.

Update: fixed issue that could leave junk characters in the string

ZIP FormatAndStreamFileFromBinary.zip   Written by Geoffrey Faivre-Malloy
File size: 2.048 bytes   Last update: 2003-06-12

Classic Version

This is a replacement for the StreamFileFromBinarySince sample that comes with IPWI. It does not use UseDLL or call the embedded function. It is more generic and just gets the file. There is one function to put it in the temp setup folder and one to copy it to any path. It uses the Propery table to pass the parameters.  See the source for details on the apis.

//Public - Available as a custom action
export prototype IScriptBinaryTableCopyFile(HWND);
export prototype IScriptBinaryTableGetTempFile(HWND);

//Private - Available only within the script
prototype MyStreamFileFromBinary(HWND, STRING,
STRING);

This custom action is written in InstallScript.

ZIP MyStreamFileFromBinary.zip    Written by  Chris Alonzo
File size: 2.394 bytes   Last update: 2001-05-05

Writing to the Installer Log File

Here is an InstallScript routine that will allow the user to write to the Windows Installer log file.

ZIP WriteToLogFile.zip    Written by Tom Gondesen
File size: 1.214 bytes   Last update: 2000-07-14

Debugging Custom Actions

There are several methods you can use to debug a DLL or EXE custom action in Windows Installer.

Using the MsiBreak Environment Variable

This is the "official" method suggested by Microsoft: To enable the debugging of a custom action, set the environment variable MsiBreak to the name of the designated action, which is case-sensitive, the same as it appears in the CustomAction and sequence tables. Debugging custom actions that are executing in the service requires the debugger to be attached to the service process (MsiExec.exe) ahead of time. For more details see topic "Debugging Custom Actions" in the Windows Installer SDK Help (msi.chm). be sure to register the MsiBreak environment-variable as a SYSTEM-environment-variable. On pre-2.0 Windows Installer it doesn't work when it is defined as a USER-variable. A reboot may be necessary to make sure all programs use the changed system environment.

Calling DebugBreak in the Custom Action Code

You can insert a DebugBreak() call at the beginning of your custom action code to invoke the debugger. For detailed instructions see InstallShield's knowledge base article Q103721.

Unforturnately, this doesn't work for custom actions called in the execute sequence on WinNT/2000 since a different process will be launched and the operating system thinks it is an unhandled exception.

Display Message Box and attach Debugger

Windows Installer expert Stein Aasmul's recommendation to debug DLL custom actions:

I find that the simplest approach is to show a message box from within the function you want to debug, and then just attach the debugger to the message box that pops up. Essentially just attaching to msiexec.exe - either the user context one or the system context one depending on how your custom action is sequenced.

To further speed things up I usually define a dialog show macro that is only enabled in debug builds and also sometimes set a debug level in the registry to determine how many dialogs to show. I.e DebugLevel = 4 shows all debug dialogs, DebugLevel = 1 shows only one dialog upon entry into the function etc...

Custom Action Debugging Support in IPWI 2.x

This article describes an undocumented and unsupported feature of InstallShield Professional - Windows Installer Edition 2.x

By setting a special registry key, you can instruct IPWI to invoke the Visual Studio debugger (or whatever development tool you use to create the DLL or EXE). This method has several advantages over the above mentioned ways:

Please read the following document for details about using the IPWI method. Note that this method is not available in ISWI version 1.x.

HTML CADebuggingIPWI.htm   Please send your feedback to mingbiaof@installshield.com
Last update: 2000-10-31

 

 

 

English News Discussions Windows Installer Related Tools More Help InstallScript About InstallSite Shop Site Search
deutsch Neuigkeiten Diskussionsgruppen Windows Installer MSI FAQ Artikel     Shop Suche

Copyright © by InstallSite Stefan Krueger. All rights reserved. Legal information.
Impressum/Imprint Datenschutzerklärung/Privacy Policy
By using this site you agree to the license agreement. Webmaster contact