MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: TryMeCreateIisSite.MM[Next]: TryMeDualPurposePackage-SupportsWinXP.MM
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->MAKEMSI Installs...->Samples Installed by MAKEMSI->Samples - Build New MSI/MSM->TryMeDllCustomAction.MM

TryMeDllCustomAction.MM

This is one of the MAKEMSI samples which build a new MSI/MSM. This MSI makes use of these "TryMe.MM" files:

  1. TryMe.ver
  2. 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]---


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: TryMeCreateIisSite.MM[Next]: TryMeDualPurposePackage-SupportsWinXP.MM


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday May 28 2022 at 3:11pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.