TryMeDllCustomAction.MM |
This is one of the MAKEMSI samples which build a new MSI/MSM. This MSI makes use of these "TryMe.MM" files:
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]---