InstallShield Tips and Techniques

July 14, 2007

Should you use CustomActionData?

Filed under: Reference Materials — shieldmaster @ 10:58 am

InstallShield 12 can be the bane of Deployment architects everywhere if there are existing MSI projects with InstallScript Custom Actions that need to be migrated to this new version!  All of their carefully worked Custom Action scripts created for earlier IS versions, will need to be re-evaluated after migrating to version 12.A severe problem that I have seen is that Custom Action written in InstallScript that are set to run Deferred will not have access to any MSI Property – there are very few exceptions, one MSI property accessable will be “CustomActionData”. So MSI Properties like “INSTALLDIR” and “PROGRAMFILES” are not accessible – no warning will be issues, just any attempt to retrieve data will result in a NULL value received.  Kind of destroys your script coding logic!

In my scripts, I tend to evaluate the workstation using InstallScript Custom Actions (Immediate Execution) and stash data in public MSI properties.  For example if I determine that Adobe Acrobat was installed, I store a boolean value (TRUE/FALSE) in an MSI Property, and the install path in another MSI Property.  Later when I want to launch the release notes, I have a InstallScript Custom Action set to Deferred to evaluate the MSI properties and take appropriate action.

With InstallShield 12 these InstallScript Custom Actions will no longer work correctly.  I will need to rework the Custom Action to store the data in the MSI Property CustomActionData.  Check out Christopher Painter’s blog notes on CustomActionData and its issues.  Normally the field would be used for a single value, but Christopher offers a technique to ’stuff’ multiple values in the field for retrieval. 

Technically a great solution, but hard to implement and a bear in long term maintenance.I feel that there is a better solution for modifying existing/legacy scripts, simply by using the registry as your sandbox.  For example, take a section of the HKLM\SOFTWARE, which is normally suggested that you place specs on your Company Name (see entries for Adobe).  Use it as a sandbox and stash installation variables gleaned during the UI Sequence and later retrieve them during the Install Execute sequence.   Here is an example of the technique that I use:

Prime RegistryJust after the dialogs have completed create a InstallScript Custom Action that will allow you to gather up all of your special MSI Properties that were initialized during previous CA’s and write them to the registry.  Here is a script extract:

RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE ); 
szRegKey = “SOFTWARE\\Install Solutions\\Framework”; 
nvType = REGDB_STRING;

szRegSubKey =   “InstallDir”;
szProgramFilesDir = INSTALLDIR;
nResult = RegDBSetKeyValueEx(szRegKey, szRegSubKey, nvType, szInstallDir,-1);
if (nResult < 0 )then
   szBuffer = “ISI–>  ERROR – szInstallDir Directory” + could not be updated in registry:  ‘%s’” ;
 Sprintf (szLogMessage, szBuffer, szRegKey);
 ISI_Fn_WriteLogFile (szLogMessage);      
else
 szBuffer = “ISI–>  INFO – szInstallDir Directory location ‘%s’ updated in registry: ‘%s’ with key of ‘%s’ “;
 Sprintf (szLogMessage, szBuffer, szInstallDir, szRegKey, szRegSubKey);
 ISI_Fn_WriteLogFile (szLogMessage);      
endif;   
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE ); 
szRegKey = “SOFTWARE\\Install Solutions\\Framework”; 
nvType = REGDB_STRING;

// Obtain MSI Property for CustomerName and update Registry
nBuffSize = 256;
szMSIProperty = “ISI_CUSTNAME”;
szRegSubKey   = “CustomerName”;
  MsiGetProperty (ISMSI_HANDLE, szMSIProperty, svValue, nBuffSize);
  //Update the CustomerName Key.
  nResult = RegDBSetKeyValueEx(szRegKey, szRegSubKey, nvType, svValue, -1);
 if (nResult < 0 )then
   szBuffer=”ISI–>  ERROR-MSI Property ‘%s’ could not be updated in registry:  ‘%s’” ;
  Sprintf (szLogMessage, szBuffer, szMSIProperty, szRegKey);
  ISI_Fn_WriteLogFile (szLogMessage);      
 else
  szBuffer=”ISI–>INFO-MSI Property ‘%s’ updated in registry: ‘%s’ w/value of ‘%s’ “;
  Sprintf (szLogMessage, szBuffer, szMSIProperty, szRegKey, svValue);
  ISI_Fn_WriteLogFile (szLogMessage);      
 endif;   

Retrieve Registry ValuesIn each InstallScript Custom Action, simply add this script at the beginning to retrieve the values from the registry and store them into variables.  It should flow seamlessly into your existing script – here is some sample script that I use:

nvSize=256;  

RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); 

szKey=”SOFTWARE\\Install Solutions\\Framework”;nType=REGDB_STRING;  

//Get the InstallDir Key.

RegDBGetKeyValueEx(szKey,”InstallDir”, nType, svInstallDir, nvSize);     

szBuffer = “Retrieved from registry key ‘%s’ the InstallDir key which was ‘%s’ “;      Sprintf (szLogMessage, szBuffer, szKey, svInstallDir );     

ISI_Fn_WriteLogFile (szLogMessage);               

//Get the Customer Name.RegDBGetKeyValueEx(szKey,”ISI_CustName”,nType,szCustName,nvSize);     

szBuffer=”Retrieved from registry key ‘%s’ the ISI_CustName key which was ‘%s’ “;     

Sprintf (szLogMessage, szBuffer, szKey, szCustName );     

ISI_Fn_WriteLogFile (szLogMessage);    

After the install has been completed, should the install variables placed in the registry be deleted?  Not necessarily, it could have use in the uninstall process.  But remember to delete them when the uninstall has completed. 

Hope this helps! 

Charles  

Enable MSI logging

Filed under: Reference Materials — shieldmaster @ 12:07 am

The use of the MSI log cannot be underestimated in its ability to resolve technical issues.  It can be complicated to review the contents, so much so there are tools available to assist you.  

But first you must ensure that a MSI log is generated for your installs – here is the best method  to have one generated each time your install is run.  Add this registry entry to the workstation/server:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer]
“Logging”=”voicewarmup”

Hint:  take the above text and save as “MSILogging.reg” and then double-click it.

Now whenever a MSI install is run – even if you perform a Modify/Repair/Remove from the Add/Remove Program Control Panel, a verbose MSI log is generated.  The log is created in the Windows Temp directory (use %TEMP% in the Start | Run dialog box to access).  Look for a recent file named MSI9999.log (where 9999 is a random number).

This is much easier to accomplish instead of creating the complex batch statement to create a MSI log during execution.

Charles

Updated:  It was noted that the correct phrase should be “voicewarmup” – thanks Colin!

Blog at WordPress.com.