The "VbsCaSetup" Command |
This command is used to schedule a preexisting VBSCRIPT custom action (its already in the "Binary" table). It also sets up the "Action Text" which gets displayed in the progress bar even if your script does not update the bar itself.
You would normally create the script with "VbsCa" but this is not required.
If you have an existing Windows Scripting Host (WSH) script which you want to use, use the "ExeCa" command to invoke "WSCRIPT.EXE". All parameters will typically be passed on the command line and no logging will take, in my mind good reasons why this should be avoided at nearly all costs. I recommend rewriting to use the "VbsCa" command instead.
This command takes these parameters:
This command will run the script from the "Binary" table (using this key). You may (or may not) have used the "VbsCa" command to create this binary.
You are referring to an "inline" script you previously defined with a "VbsCa" command.
This command will retrieve the script and imbed it in the "Target" column of the "CustomAction" table.
This value will contain newlines. Some msi editors such as "ORCA" will not display these values well. To examine the contents you can copy the column and paste it into some text editors such as "wordpad". When examining the code you may notice that characters like '[' have been escaped with '[\[]' etc.
Note that this parameter is not required for inline scripts.
If this parameter is supplied then the setting up of the data uses the sequence number provided and the VBS takes the next "slot". You would not need to use the "KEY" parameter to specify any specific value to pick up the "CustomActionData" if this parameter is used.
There will typically be a lot of standard actions at known fixed locations (which may however differ in sequence number or even order relative to one another with different templates). Click here for the default "InstallExecuteSequence" and "InstallUISequence" sequencing details.
Normally you try not to duplicate sequence numbers but it is probably OK to do so as long as you don't care which one executes first! One possible exception would be deferred custom actions where the custom action data needs to be setup before execution. You should get a validation message to indicate a duplicated number (note that validation can't know whether custom action conditions are mutually exclusive etc).
The sequencing information (see some default sequencing) can be supplied in a number of formats:
Basically you describe a range of valid values and whether you prefer the value to be chosen from the lower (default) or higher end.
The range should be specified in the format "lower - higher". Either value can be omitted, be specified as an integer such as "1000" or the name of an action such as "InstallFiles". The default value for the lower end is "1" and for the higher "32767" and leading and trailing spaces for each are stripped. The minimum and maximum values can be returned as the range is inclusive.
By default MAKEMSI will choose a number as close as possible to the lower end, if you wish it to be as high as possible then begin the specification string with "<".
Some Examples:
You should of course be aware of what your script does, for example if it moves a custom action that you have already sequenced other actions relative to then that would probably be "bad"!
Note that you can supply an empty list (no tables) if you just want to define the custom action but not sequence it, however you must confirm this by supplying a sequence number of 0 (zero) on the "SEQ" parameter can you should also supply "" for the "CONDITION" parameter (value ignored).
I have captured a large number of "sample properties" which could be used in any conditions. Note that the values of some properties may not be available at all times and in some cases are modified during processing.
You can also use any of the following predefined conditions:
#define? CONDITION_ALREADY_INSTALLED Installed ;;Repair, uninstall etc. #define? CONDITION_INSTALL_ONLY not Installed ;;Doesn't include a repair, uninstall etc! #define? CONDITION_UNINSTALL_ONLY Installed and REMOVE~="ALL" ;;Complete uninstall - HIGHLY RECOMMENDED at you read the "REMOVE" properties MAKEMSI doco! #define? CONDITION_EXCEPT_UNINSTALL not (<$CONDITION_UNINSTALL_ONLY>) ;;Install, Repair etc (all but complete uninstall) #define? CONDITION_IS_WIN2000 VersionNT = "500" ;;Is OS WIN2000? #define? CONDITION_IS_WINXP VersionNT = "501" ;;Is OS WINXP? #define? CONDITION_IS_VISTA VersionNT = "600" ;;Is OS WINDOWS Vista? #define? CONDITION_IS_WINDOWS_7 VersionNT = "601" ;;Is OS WINDOWS Windows7 #define? CONDITION_UI_NONE UILevel = 2 ;;Silent Install #define? CONDITION_UI_BASIC UILevel = 3 #define? CONDITION_UI_REDUCED UILevel = 4 #define? CONDITION_UI_FULL UILevel = 5 ;;"Normal" #define? CONDITION_UI_NO_DIALOGS UILevel <> 5 ;;Don't bother user with popup dialogs, opening readme files etc. #define CONDITION_PER_MACHINE Version9X or (ALLUSERS = 1) ;;True if per-machine install. #define CONDITION_PER_USER not (<$CONDITION_PER_MACHINE>) ;;True if per-user (not per-machine) install.
This parameter accepts one or more space separated attributes which are processed in left to right order. Available attributes are (not all may apply):
A deferred (in-script) custom action must be sequenced between the "InstallInitialize" and "InstallFinalize" actions (or you will get a 2762 error) and data is passed via the "CustomActionData" property.
All deferred actions are executed in a single pass by the server "MSIEXEC.EXE" service (a separate process) after being combined in a "script".
All immediate custom actions scheduled between the "InstallInitialize" and "InstallFinalize" actions (regardless of their sequence number) are executed before deferred ones.
This should only be used as a last resort when executing some poorly written piece of "cr*p" (or perhaps if it's success is not critical to the install).
Rollback custom actions (and so also the "worker" custom action) must be "deferred" and sequenced between "InstallInitialize" and "InstallFinalize".
There are circumstances where a custom action may still run with system privileges.
Lack of this attribute on deferred custom actions is a common reason for failures on Vista.
The CustomActionData property is also not logged when the installer executes the custom action.
Because the installer sets the value of CustomActionData from a property with the same name as the custom action, that property must be listed in the "MsiHiddenProperties" property to prevent its value from appearing in the log.
If the number begins with "0x" (case insensitive) then the number is being supplied as a hexadecimal value otherwise its interpreted as being in decimal.
You may need to supply a numeric value such as "+0x0001" if I haven't provided a suitable alias above...
EXAMPLE - Simple INLINE (type 38 CA) |
<$VbsCa Binary="!SimpleVbs"> InstallDir = session.property("INSTALLDIR") InstallDir = left(InstallDir, len(InstallDir)-1) 'MsgBox "DEBUG: The INSTALLDIR without a trailing backslash ===> " & InstallDir session.property("DIR_NO_SLASH") = InstallDir ;;You will see this action logged in any verbose log <$/VbsCa> <$VbsCaSetup Binary="!SimpleVbs" Seq="CostFinalize-" SeqTable="InstallExecuteSequence" CONDITION=^<$CONDITION_INSTALL_ONLY>^>
EXAMPLE - Binary - With CustomActionData |
;--- Set up the 2 parameters (CustomActionData) ----------------------------- #data "Fred" "Name1" 'Name 1 Value' ;;Parameter 1 (name + value) "Name2" "[INSTALLDIR]" ;;Parameter 2 #data ;--- Deferred Custom Action which accesses 2 passed parameters -------------- <$VbsCa Binary="TestCustomActionDataPassing.vbs" DATA="Fred"> <$VbsCaEntry "Install"> ;--- Do something ---------------------------------------------------- Show("Install: NAME1=" & VbsCaCadGet("Name1")) Show("Install: NAME2=" & VbsCaCadGet("Name2")) <$/VbsCaEntry> '======================= sub Show(Text) '======================= CaMsgBox "I", Text end sub <$/VbsCa> ;--- Set up the Deferred custom action passing the CustomActionData --------- <$VbsCaSetup Data="Fred" Binary="TestCustomActionDataPassing.vbs" Entry="Install" Seq="InstallFiles-" CONDITION=^<$CONDITION_INSTALL_ONLY>^>
EXAMPLE - Others |
;--- Create a VBSCRIPT and add to the binary table -------------------------- #( '<?NewLine>' #define InstallationOnTrap ;--- This code must be called to "clean up" after failed install --------- 'clean up code statement 1 'clean up code statement 2 'clean up code statement 3 #) <$VbsCa Binary="TEST.vbs"> <$VbsCaEntry "Install" OnTrap="<$InstallationOnTrap>"> ;--- Do something ---------------------------------------------------- UserFunction("Called during Install...") ;--- Set the return code --------------------------------------------- '<$VbsCaEntryName> = 1603 ;;Error Return code <$/VbsCaEntry> <$VbsCaEntry "UnInstall"> ;--- Do something ---------------------------------------------------- UserFunction("Called during UNInstall...") <$/VbsCaEntry> '======================= sub UserFunction(Text) '======================= CaMsgBox "I", Text end sub <$/VbsCa> ;--- Call the above script during install and uninstall --------------------- <$VbsCaSetup Binary="TEST.vbs" Entry="Install" Seq="InstallFiles-" CONDITION=^<$CONDITION_INSTALL_ONLY>^> <$VbsCaSetup Binary="TEST.vbs" Entry="UnInstall" Seq="InstallFiles-" CONDITION=^<$CONDITION_UNINSTALL_ONLY>^>