\
MAKEMSI Installs...
Samples Installed by MAKEMSI
Samples - Build New MSI/MSM
TryMeDllCustomAction.MM
This is one of the MAKEMSI samples which build a new MSI/MSM.
This MSI makes use of these "TryMe.MM" files:
- TryMe.ver
- TryMe.rtf
You must have installed a number of "MinGw" packages as well as
the Windows Installer SDK for this to work.
The "Browse for File Dialog" tip shows how to add to this
sample to display a browse dialog.
;----------------------------------------------------------------------------
; MODULE NAME: TryMeDllCustomAction.MM
;
; $Author: USER "Dennis" $
; $Revision: 1.9 $
; $Date: 26 Jun 2010 10:20:56 $
; $Logfile: C:/DBAREIS/Projects.PVCS/Win32/MakeMsi/TryMeDllCustomAction.MM.pvcs $
;
; DESCRIPTION
; ~~~~~~~~~~~
; Demonstrates how the free MinGw compiler can be used by MAKEMSI to build
; compile and add a DLL to the MSI.
;
; Note that this requires multiple "MinGw" packages and the Microsoft
; Platform SDK to have been downloaded to work.
;
; Just because this sample doesn't use certain parameters of some functions
; does not means that you won't require them for a working MSI
; (depending on what you are trying to do). The most likely parameter
; you will want to add is the "TYPE" parameter of the "DllCa" command.
;
; As with all samples any "configuration" you always do should be moved
; to a single common header file.
; This also goes for any common C/C++ functions etc.
; If you do the same thing in 2 places, rethink...
;
;
; ###############################################################
; #### MS DELIBERATE SABOTAGE OR PERHAPS JUST PLAIN STUPIDITY ###
; ###############################################################
; MS have knowingly or unknowingly built the SDK so that it is not
; standalone (needs their C compiler). Not only that each SDK release
; has different bugs (making the former more likely).
;
; I had to find and download these files for the 4.5 SDK:
;
; 1. "SpecStrings.h" - Found at "http://www.koders.com/c/fidEB140B5CB1BB104F62074344D8612CFA3BA97CE5.aspx?s=ShellExecute+SE_ERR_NOASSOC"
; 2. "sal.h" - Found at "http://www.portaudio.com/trac/browser/portaudio/trunk/src/hostapi/wasapi/mingw-include/sal.h"
;
; The files were put into "INCLUDE_MS" I then added this code to
; the start of this file:
; #define DLLCA_C_MINGW_INCLUDE_DIRECTIVES -I "C:\Program Files (x86)\MakeMsi\Samples\TryMe\Create MSI Installers\INCLUDE_MS" -I "C:\MinGW\include" -I "<$PLATFORM_SDK_INCLUDE_DIR>"
; #( '<?NewLine>'
; #define MS_POSSIBLY_DELIBERATE_SABOTAGE_OR_MAYBE_JUST_PLAIN_STUPIDITY ;;Or even care factor = 0
;
; <?Hash>include "sal.h" ;;Fix "__reserved" missing
; #)
;
; And added "<$MS_POSSIBLY_DELIBERATE_SABOTAGE_OR_MAYBE_JUST_PLAIN_STUPIDITY>" on
; a new line at the end of the defintion of "DllCa-C_INCLUDE_HEADERS_USER" below.
;
;
; SOME MESSAGES
; ~~~~~~~~~~~~~
; * http://tech.groups.yahoo.com/group/makemsi/message/2777
; * http://tech.groups.yahoo.com/group/makemsi/message/2778
; * http://tech.groups.yahoo.com/group/makemsi/message/2779
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;--- Define other header stuff we need/want ---------------------------------
;----------------------------------------------------------------------------
#( '<?NewLine>'
#define DllCa-C_INCLUDE_HEADERS_USER
<?Hash>include <tchar.h>
#)
;----------------------------------------------------------------------------
;--- Include MAKEMSI support (with my customisations and MSI branding) ------
;----------------------------------------------------------------------------
#define VER_FILENAME.VER TryMe.Ver ;;I only want one VER file for all samples!
#include "ME.MMH"
;----------------------------------------------------------------------------
;--- We will look for "UPX.EXE", if we find it we will configure MAKEMSI ----
;--- to compress the generated DLL... ----
;----------------------------------------------------------------------------
<$GetFullBuildTimeFileName RcVar="@@UpxFile" Macro="UPX.EXE" File="upx.exe" MustExist="N"> ;;See "sundry.mmh"
#if [@@UpxFile = '']
;--- Non-fatal so we'll just tell user ----------------------------------
#(
#define+ DLLCA-C_COMPRESS_DLL_COMMAND_LINE ;;Need to OVERRIDE value (we couldn't do it earler or "GetFullBuildTimeFileName" wouldn't exist!)
echo INFO: DLL not being compressed (UPX.EXE not found)
#)
#elseif
;--- "UPX.EXE" was found ------------------------------------------------
#(
;--- Define the macro that MAKEMSI will use as required -------------
#define+ DLLCA-C_COMPRESS_DLL_COMMAND_LINE ;;Need to OVERRIDE value (we couldn't do it earler or "GetFullBuildTimeFileName" wouldn't exist!)
;--- I expect "upx.exe" to be in the "PATH" environment variable ----
"<??@@UpxFile>" ;;Full name of UPX.EXE (get from "http://upx.sourceforge.net/")
;--- I want highest compression -------------------------------------
--best
;--- Backup the DLL as a debugging aid... ---------------------------
-k
#)
#endif
;---[4Doco-DllCa-C]---
;--- Create the DLL source, compile and add to MSI --------------------------
<$DllCa-C Binary="MyTestDll.dll">
//============================================================================
static void PopupMessage(MSIHANDLE hInstall, char * MessageText)
//============================================================================
{
MSIHANDLE hRecord = MsiCreateRecord(0);
MsiRecordSetString(hRecord, 0, TEXT(MessageText));
MsiProcessMessage(hInstall, INSTALLMESSAGE_USER + MB_OK, hRecord);
MsiCloseHandle(hRecord); ;;Close handle or will get logged: ...: Leaked MSIHANDLE (7) of type 790531 for thread 4148
}
//============================================================================
static void DoSomething(MSIHANDLE hInstall)
//============================================================================
{
//--- Update top line of "progress bar" (also logged) ------------------
CaDebug(PROGRESS_ACTION, "Step - Executing DLL custom action.");
//--- Get the ProductName & ProductVersion properties (immediate CA) ---
TCHAR ProductName[100] = {0};
TCHAR ProductVersion[50] = {0};
DWORD ProductNameLng = sizeof(ProductName) / sizeof(TCHAR);
DWORD ProductVersionLng = sizeof(ProductVersion) / sizeof(TCHAR);
MsiGetProperty(hInstall, TEXT("ProductName"), ProductName, &ProductNameLng);
MsiGetProperty(hInstall, TEXT("ProductVersion"), ProductVersion, &ProductVersionLng);
//--- Log the properties -----------------------------------------------
CaDebugv(PROGRESS_DETAIL, "Step Detail - you should see this on the progress dialog (while the MsgBox() is up). This is version %s of product: %s", ProductVersion, ProductName);
//--- Never use a message box like this in production code (prevents silent install) ---
//MessageBox(NULL, "CustomAction DLL says Hi", "HI FROM: <$ProdInfo.ProductName>. Never actually use a message box like this as it prevents silent installs!", MB_OK);
PopupMessage(hInstall, "DLL CA has finished and is about to exit...\n\nNote that this dialog won't display in silent mode...");
}
//============================================================================
<$DllCaEntry "InstallCode">
//============================================================================
{
//--- Call a function we create above --------------------------------
DoSomething(hInstall);
//--- Return successful to Windows Installer -------------------------
return(0);
}
<$/DllCaEntry>
<$/DllCa-C>
;--- Now call the entry point where and when desired ------------------------
<$DllCa Binary="MyTestDll.dll" Seq="CostFinalize-" Entry=^<$DllCaEntry? "InstallCode">^ Type="Immediate" Condition="<$DLLCA_CONDITION_INSTALL_ONLY>">
;---[4Doco-DllCa-C]---