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]: Commands[Next]: {NL} code (NewLine)
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Source Code->Commands->#DATA for Commands

#DATA for Commands

Many custom action related MAKEMSI commands take a #data structure when passing parameters to a deferred CA (see the "CustomActionData" property). The name of the #data structure is passed in the "DATA" parameter

The #data structure contains two columns, the first is how the custom action will refer to it when its wants its value and the second is the value. The "name" is case sensitive! The "value" would typically contain be a formatted value, an example follows:

#data 'CaData' 2                                      ;;The optional 2nd parm ("2") ensures that the number of columns you supply is validated
    "INSTALLDIR"        "[INSTALLDIR]"                ;;Location of installation directory
    "COMPLUS_DLL_1"     "[#<$SAMPLE_COM+DLL_#1>]"     ;;Want full install time location of specified file "RowKey"
    "SomeFile"          "[INSTALLDIR]ReadMe.txt"      ;;Another way to refer to a file (where rowkey isn't known)
#data

The "COMPLUS_DLL_1" definition is generally better than that for "SomeFile" because if the file didn't get installed (a mistake) then an MSI Validation message would let you know of this. Also if the file was in a component that didn't get installed you'd get a install time error.

The "VbsCaCadGet()" and "VbsCaCadReplace()" are VBSCRIPT routines that can be used to read information from the #data.

EXAMPLE

;--- Add file ---------------------------------------------------------------
<$Component "Doco" Create="Y" Directory_="INSTALLDIR">
    <$File Source="out\doco\makemsi.chm">
<$/Component>

;--- Open file near end of install ------------------------------------------
#data "CaDataExecute"
   "FileToOpen" "[INSTALLDIR]MakeMsi.CHM"
#data
<$VbsCa Binary="OpenFile.vbs" DATA=^CaDataExecute^>
   ;--- INSTALL -------------------------------------------------------------
   <$VbsCaEntry "OpenFileNearEndOfInstall">
       ;--- Build the command we wish to execute ----------------------------
       dim StartCmd : StartCmd = "start """" """ & VbsCaCadGet("FileToOpen") & """"

       ;--- Execute the command ---------------------------------------------
       VbsCaRunSync StartCmd, 0, ""         ;;Ignore RC
   <$/VbsCaEntry>
<$/VbsCa>
<$VbsCaSetup Binary="OpenFile.vbs" Entry="OpenFileNearEndOfInstall" Seq="StartServices-" CONDITION=^<$CONDITION_INSTALL_ONLY>^ DATA=^CaDataExecute^>

EXAMPLE - How to use within Macro

The "#data" structure can be a bit tricky to imbed in a macro, if you don't need to (there are no parameters being substituted into it) then its easier to put it outside of the macro.

Here is one workaround if parameters are being passed into it (creates temporary file):

#define @@TmpDataFile <?TmpDir>\TmpCaData_@@.tmp
#(
    #define TmpFileMethod

    ;--- Create a temporary file containing the #data structure then read it back ---
    #output '<$@@TmpDataFile>' ASIS OTHER   ;;Start building temprary file
    #( '<?NewLine>'
        <?Hash>data "CaDataTmpFile" 2
            "PARM_01" "{$PARM_1}"
            "PARM_02" "{$PARM_2}"
        <?Hash>data
    #)
    #output                                 ;;Finished building it
    #include '<$@@TmpDataFile>'             ;;Read the file containing the "#data"

    ;--- Rest of macro ------------------------------------------------------
    <$VbsCa Binary="SomeTmpFile.vbs" DATA="CaDataTmpFile">
    #( '<?NewLine>'
        <$VbsCaEntry "DoesSomething">
           '...
        <$/VbsCaEntry>
    #)
    <$/VbsCa>
#)

<$TmpFileMethod PARM_1="Tmp01" PARM_2="Tmp02">      ;;Test macro

Here is another and probably better method:

#(
    #define NewLineMethod

    #data "CaDataNl" 2
    #( '<?NewLineInMacro>'              ;;Make the following look like separate lines
        "PARM_01" "{$PARM_1}"
        "PARM_02" "{$PARM_2}"
    #)
    #data

    ;--- Rest of macro ------------------------------------------------------
    <$VbsCa Binary="SomeNl.vbs" DATA="CaDataNl">
    #( '<?NewLine>'
        <$VbsCaEntry "UnInstall">
           '...
        <$/VbsCaEntry>
    #)
    <$/VbsCa>
#)

<$NewLineMethod PARM_1="Nl01"  PARM_2="Nl02">


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]: Commands[Next]: {NL} code (NewLine)


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.