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]: Tweek.MM[Next]: ErrorTemplates.TXT
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 - Not building a new MSI->FixMergeModules.MM

FixMergeModules.MM

This shows the manipulation of an existing MSM (merge module) to fix some badly written Visual Studio .NET merge modules which amongst other issues refer to "TARGETDIR" in the "Component" table.

This typically causes some or all files to be installed into a root (usually "C:\") and the location can't be redirected.

Do MS test their merge modules? They certainly don't fix them or run them through their own validation suites... Years later still not fixed, just some vague promise, amazing...

This script will create a new "Directory" table entry and update any direct "TARGETDIR" references to refer to this new directory. After the fix the "DIR" parameter of the "MergeModule" command will work (as will "ORCA" etc).

;----------------------------------------------------------------------------
;
;    MODULE NAME:   FixMergeModules.mm
;
;        $Author:   USER "Dennis"  $
;      $Revision:   1.2  $
;          $Date:   01 Nov 2006 17:38:04  $
;       $Logfile:   C:/DBAREIS/Projects.PVCS/Win32/MakeMsi/FixMergeModules.mm.pvcs  $
;      COPYRIGHT:   (C)opyright Dennis Bareis, Australia, 2003
;                   All rights reserved.
;
;    DESCRIPTION
;    ~~~~~~~~~~~
;    This sample shows how some badly written VS .net modules can be fixed.
;
;    The bug in this case is that "Component" table entries reference
;    "TARGETDIR" which resulting in a merge module where files typically
;    install into the root directory (C:\) and can't be redirected.
;    The rule being broken is:
;
;             Merge module tables other than the Directory table must
;             not directly reference directory locations to TARGETDIR.
;             The location of such a reference changes if the value
;             of TARGETDIR is changed by the user
;
;    This code creates a new Directory key with a random name and updates
;    and "Component" tables entries that specify "TARGETDIR" to use the new
;    directory entry.
;
;    The code will report an error if at least one entry wasn't
;    fixed (@OK='? >= 1').
;----------------------------------------------------------------------------


;----------------------------------------------------------------------------
;--- Name must be passed from command line using "/Define:" switch... ---
;----------------------------------------------------------------------------
;#define MSM TestMergeModule.msm
#ifndef MSM
    #error ^You should have passed the name of the merge module to be fixed on the command line!^
#elseif
    ;--- User passed value (on command line) --------------------------------
    #define  MsmBefore <$Msm>
    #define? MsmAfter  Fixed\<$Msm $$FilePart:name>  ;;Put into "Fixed" directory (by default, let user override)
#endif


;----------------------------------------------------------------------------
;--- Load MAKEMSI support ---------------------------------------------------
;----------------------------------------------------------------------------
#define  VALID_ValidateTheGeneratedMsi   ;;Don't validate (do nothing)
#include "OpenMsi.MMH"


;----------------------------------------------------------------------------
;--- Generate a random Key --------------------------------------------------
;----------------------------------------------------------------------------
#DefineRexx ''
   @@RandomDirKey = "TARGETDIR_FIX_" || random(1,99999);
#DefineRexx


;----------------------------------------------------------------------------
;--- Copy .MSM and Fix the Copy ---------------------------------------------
;----------------------------------------------------------------------------
<$Msi "<$MsmAfter>" Template="<$MsmBefore>">
   ;--- Set up the directory entry which will replace "TARGETDIR" references ---
   <$Directory Key="<??@@RandomDirKey>" Parent="TARGETDIR" DIR="{.:Ignored}">

   ;--- Update Component table ----------------------------------------------
   <$Table "Component">
   #(
       ;--- No componnet should reference "TARGETDIR" (replace with our new key) ---
       <$Row
               @Where="Directory_ = 'TARGETDIR'"        ;;Look for entries which incorrectly refer to "TARGETDIR"
                  @OK='? >= 1'                          ;;We will abort with error if we don't find at least one incorrect entry
           Directory_="<??@@RandomDirKey>"              ;;Fix all found entries by pointing to our new directory entry
       >
   #)
   <$/Table>
<$/Msi>


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]: Tweek.MM[Next]: ErrorTemplates.TXT


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.