#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">