cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Writing to the Log File from a Custom Action in an MSI

Writing to the Log File from a Custom Action in an MSI

Summary

In an MSI, It is possible for most custom action types to write to the log.

Synopsis

In an MSI, It is possible for most custom action types to write to the log.

Discussion

In an MSI, it is possible custom actions to write to the MSI log as long as they are not written in managed code. In order to have a custom action write to the MSI log, refer to the appropriate section below.

InstallScript Custom Action:
In an InstallScript custom action, SprintfMsiLog can be called to write a string to the MSI log file. For example, the following InstallScript code prototypes and defines an InstallScript custom action called LoggingTestInstallScript.
#include "ifx.h" 
// standard custom action 
prototype export prototype LoggingTestInstallScript(HWND);

// custom action definition 
function LoggingTestInstallScript(hInstall) 
begin 
     SprintfMsiLog("Calling LoggingTestInstallScript...");
     // return success to MSI 
     return ERROR_SUCCESS; 
end;



After built and run, the MSI log will contain something similar to:
InstallShield 25:00:00: Invoking script function LoggingTestInstallScript
1: Calling LoggingTestInstallScript...
InstallShield 25:00:00: CallScriptFunctionFromMsiCA() ends
Action ended 25:00:00: callLoggingTest. Return value 1.



The SprintfMsiLog function is similar to the Sprintf and SprintfBox functions in that it can handle placeholders ("%s" or "%d" fields, called "format specifiers") in the message string to splice in the values of string or numeric variables.

PowerShell Custom Action: Starting with InstallShield 2015, PowerShell custom actions within an MSI can now write to the log. The following example shows the necessary cmdlet and its usage.
trace-info ?LogMessage ?I am a PowerShell custom action?

Prior to InstallShield 2015, PowerShell custom actions within an MSI could not write to the log.

VBScript Custom Action: With VBScript, the general process is to assemble a record containing the message information, and then send the record to the running installation. Installer.CreateRecord can be used to create the message record, and Session.Message can be used to send the record to the installer. The following code shows an example of how to follow this process to write to the log.
Const msiMessageTypeInfo = &H04000000 
' create the message record 
Set msgrec = Installer.CreateRecord(1)
 field 0 is the template 
msgrec.StringData(0) = "Log: [1]" 
' field 1, to be placed in [1] placeholder 
msgrec.StringData(1) = "Calling LoggingTestVBS..." 
' send message to running installer 
Session.Message msiMessageTypeInfo, msgrec



After built and run, the MSI log will contain something similar to:
Action 25:00:00: callLoggingTestVBS. 
Action start 25:00:00: callLoggingTestVBS. 
[...lines omitted...] 
Log: Calling LoggingTestVBS... 
Action ended 25:00:00: callLoggingTestVBS. Return value 0.

MSI DLL Custom Action: In an MSI DLL custom action, the process of writing to the log file is similar to the VBScript code, except that MsiCreateRecord is used to create the message record and MsiProcessMessage is used to pass the record to the running installer. For example, see the following code.
#pragma comment(lib, "msi.lib") 
#include <msi.h>
#include <msiquery.h>
#include <stdio.h>
// standard MSI DLL custom action signature 
UINT __stdcall LoggingTestCpp(MSIHANDLE hInstall)
{ 
     PMSIHANDLE hRecord = MsiCreateRecord(1);
     // field 0 is the template 
     MsiRecordSetString(hRecord, 0, "Log: [1]");
     // field 1, to be placed in [1] placeholder
     MsiRecordSetString(hRecord, 1, "Calling LoggingTestCpp...");
     // send message to running installer 
     MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRecord);
     return ERROR_SUCCESS; 
}



As usual with MSI DLL?s, a .DEF file must also be created to properly export the function names from the DLL. Following the above example, a sample .DEF file would contain:
LIBRARY "LoggingTestCpp" ; DLL name 
EXPORTS ; exported function names 
     LoggingTestCpp


After built and run, the MSI log will contain something similar to:
Action 25:00:00: callLoggingTestCpp. 
Action start 25:00:00: callLoggingTestCpp. 
[...lines omitted...] 
Log: Calling LoggingTestCpp... 
Action ended 25:00:00: callLoggingTestCpp. Return value 1.

100% helpful (1/1)
Comments

Why doesn't this KB article have example C# code for Managed Code Custom Actions?

Version history
Last update:
‎Jun 27, 2018 10:49 PM
Updated by: