InstallShield Tips and Techniques

July 26, 2010

Primer on creating InstallScript Custom Actions

Filed under: InstallShield Scripting, Reference Materials, Techniques — shieldmaster @ 10:11 pm

I extensively use InstallScript for my custom actions – it provides great flexibility in accomplishing specialized requirements.  I have tried some custom actions using VBScript – but I have encountered some hardened Operating Systems in which VBScripts are considered malware and they have removed the extension association for .vbs – so your custom actions will fail.

In this blog, I will walk you thru the steps needs to create and sequence a custom action using InstallScript.  As an example, I will create scripts that will determine what the Operating system and log it to the MSI logfile.

  1. Create the initial script file by right-clicking on the InstallScript file and selecting “New Script File

2.  A new file “setup.rul” will appear with quite a lot of commentary.  In my InstallScript functions, I want only the following to appear in the setup.rul:

  • Includes for InstallScript functions and any Windows API functions
  • Prototype statements for all InstallScript functions called by the Script Engine
  • Prototype statements for all InstallScript functions called by other script functsion.
  • Include statement for other script RUL files.

Remove the script statements and replace with these entries

/////////////////////////////////////////////////////////////////
//
//       IIIIIII SSSSSS   IIIIIII
//           II       SS                II             Install Solutions, Inc.
//          II        SSSSSS      II               (c) 2001-2010, Install Solutions, Inc.
//         II                 SS      II              All rights reserved.
//    IIIIIII  SSSSSS   IIIIIII
//
//  This template script provides the code necessary to build an
//  entry-point function to be called in an InstallScript custom
//  action.
//
/////////////////////////////////////////////////////////////////
// Include Ifx.h for built-in InstallScript function prototypes,
// for Windows Installer API function prototypes and constants
#include “ifx.h”
// Prototype statements for Custom Action entry points export prototype ISI_CheckOS(HWND);
// Prototype statements for functions called by other Scripts prototype ISI_WriteLogFile(STRING);
// Include statements for external script files
#include “ISI_CheckOS.rul”
#include “ISI_WriteLogFile.rul”

For each Custom Action that is called directly by the script engine, it will need a “prototype” statement.  The only Custom Action (CA) we will be calling will be “ISI_CheckOS”.  The script for that CA will call another script function “ISI_WriteLogFile” that will submit an logging line to the MSI logfile.

Now, create two more script files by right-clicking on the same files section and create:

  • ISI_CheckOS.rul
  • ISI_WriteLogFile.rul

Note: that if the extension .RUL is not included, the InstallShield IDE will not properly color code the variables

Within the script RUL file for “IS_CheckOS.rul” enter the following:

////////////////////////////////////////////////////////////
//
//       IIIIIII SSSSSS   IIIIIII
//           II       SS                II             Install Solutions, Inc.
//          II        SSSSSS      II               (c) 2001-2010, Install Solutions, Inc.
//         II                 SS      II              All rights reserved.
//    IIIIIII  SSSSSS   IIIIIII
//
// Function: ISI_CheckOS
// Purpose: This function will be called by the script engine
// when Windows Installer executes your custom action
// and will verify that the Operating System version
// is correct.
//////////////////////////////////////////////////////////////

function ISI_CheckOS (hMSI)
STRING szParm, szPath;
STRING strKey;
NUMBER nvSize, nResult, nReturnCode;
STRING szBuffer, szLogMessage;
begin
//WriteToLogFiles
ISI_WriteLogFile (“ISI–> Entering ISI_CheckOS Function”);
// Approve Windows XP Workstation
if (SYSINFO.WINNT.bWinXP) then
szLogMessage = “ISI–> Operating System is Windows XP “;
ISI_WriteLogFile (szLogMessage);
nReturnCode = 0;
goto ExitCheckOS;
endif;
// If WinXP was not found, then -1 will be returned
szLogMessage = “ISI–> Operating System is not an approved OS”;
ISI_WriteLogFile (szLogMessage);
nReturnCode = -1;
ExitCheckOS:
//WriteToLogFiles
ISI_WriteLogFile (“ISI–> Exiting ISI_CheckOS Function”);
return nReturnCode;
end;

The CheckOS function accomplishes the following:

  • Immediately upon entry into the CA – will log a message to the MSI Logfile that entry was accomplished
  • Using predefined constant – will check if the OS is Windows XP and if it is then will log a message to the MSI Log file and pass a 0 (represents a good return code) back to the MSI Engine.
  • If the Operating System was not Windows XP, it will log that it was not and set the return code to be -1 (bad return code)
  • Prior to exiting the Script function, will log its exit to the MSI logfile.

Note:  if the InstallScript Custom Action has the Return Processing option set to “check exit code’, then a -1 passed back to the MSI Engine will abort the installation.

Within the script RUL file for “IS_WriteLogFile.rul” enter the following:

/////////////////////////////////////////////////////////////////
//       IIIIIII SSSSSS   IIIIIII
//           II       SS                II             Install Solutions, Inc.
//          II       SSSSSS      II               (c) 2001-2010, Install Solutions, Inc.
//         II                SS      II              All rights reserved.
//    IIIIIII  SSSSSS   IIIIIII
// Function:  ISI_WriteLogFile
//
//  Purpose:  This function will be called by the script engine
//            when Windows Installer executes your custom action
//            and will write entries to the MSI LogFile
/////////////////////////////////////////////////////////////////
function ISI_WriteLogFile(szLogMessage)
STRING  szTimeParm;
STRING  szDate, szTime;
NUMBER  nResult;
begin
// Get Time and Date information to append to log message
GetSystemInfo ( DATE, nResult, szDate );
GetSystemInfo ( TIME, nResult, szTime );
szTimeParm = “[” + szDate + “:” + szTime + “]”;
//WriteMessageToMSILog
SprintfMsiLog (“ISI CA Msg: %s %s”, szTimeParm, szLogMessage);
end;

The WriteLogFile function accomplishes the following:
    • Obtains the time and date stamps and appends it before the log message.
    • Write the log message to the MSI Logfile

Now to create the CA, go to the Custom Actions section on the left most panel, and right click on the Custom Actions entry in the middle panel:

Select “New InstallScript” and a new entry will be created – title this CA “ISI_CheckOS” and press enter.  Now we will fill in the CA selections:

For the simple InstallScript Custom Action, enter the following selections:

Function Name – using the drop-down, select the script prototype function “ISI_CheckOS” – which should appear in the drop-down selection.  If it does not, it is possible you will need to either build the application or save and reopen the InstallShield project.

Return Processing – select “Synchronous (Check exit code)”

In-Script Execution – select “Immediate Execution”

Execution Scheduling – select Always Execute

UI Sequence –  using the drop-down, select “After CostInitialize”

UI Sequence Condition – enter “NOT Installed”

Well, this should give you an excellent example on how to create an InstallScript Custom Action.

Hope this helps!

ShieldMaster

Advertisements

3 Comments »

  1. Hi, a coworker forwarded me a link to this page. I was wondering if you have any tips on logging from a Standard DLL Custom Action written in C#?

    Thank you

    Comment by Jim — November 23, 2010 @ 2:23 pm

    • No I don’t Jim. Hopefully someone will reply with some tips!

      ShieldMaster

      Comment by shieldmaster — January 25, 2011 @ 9:38 pm

  2. Hi I’m having problems while creating a custom action in installShield, hope you can help me!
    I have one msi lets call it (MainInstall.msi), in wich I add one merge module (AddModule), this merge module contains many components but just one of those components has to be installed.

    For that I have one condition
    Example: if the value of the property “PrCode” is equal to “Brenda” the component “A” will be installed.
    My problem is that I need to set the value of the property “PrCode”,in the main program( MainInstall.msi) and the one that use that value is the merge module (AddModule).

    My question is, is there any way to set the value of the PrCode property from the mainInstall, if where I use it is in the Merge module?
    I tried to do with custom actions but… nothing!!

    Please can you help me?

    Comment by Br3nda — January 6, 2011 @ 10:07 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: