SetupBuilder
SetupBuilder copied to clipboard
DSL-Extension for MSI-embedded (PowerShell-)script?
When using SetupBuilder for packaging MSIs we often have the need to run a script as part of the installation, which is usually done via a custom action. While SetupBuilder already provides a means to run a script (or really any command) after the installer (via setupBuilder.runAfter
), this runs asynchronously and is therefore not useful as part of the actual installation (especially if a failed execution should also fail the installation).
Normally this would be solved by using a custom WXS template with an added custom action:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product>
<CustomAction Id="afterInstScript"
ExeCommand="PowerShell.exe -ExecutionPolicy UnRestricted -File afterInst.ps1"
Directory="INSTALLDIR" Execute="deferred" Return="asyncWait"/>
<InstallExecuteSequence>
<Custom Action="afterInstScript" After="InstallFiles" />
</InstallExecuteSequence>
</Product>
</Wix>
To get rid of the additional WXS file I propose an extension to the msi-DSL to expose the relevant custom action and sequence parameters:
msi {
runCommand {
command = "cmd.exe /c echo done" // one of command || powershell (see below) is mandatory
before = "InstallInitialize" // mandatory, possibly with default
execute = "deferred" // mandatory, possibly with default
return = "asyncWait" // mandatory, possibly with default
}
}
These values would be passed through as-is to the respective attributes in the resulting WXS.
Since the most common use case of this nowadays (for us anyway) is to run a PowerShell script and there is no means to embbed one today, instead of command
the following should be possible:
msi {
runCommand {
powershell { // one of command || powershell is mandatory
script = "" // mandatory
parameters = "" // optional
}
before = "InstallInitialize" // mandatory, possibly with default
execute = "deferred" // mandatory, possibly with default
return = "asyncWait" // mandatory, possibly with default
}
}
This would leverage PowerShell's encoded-command option to avoid hassling with temporary script files by using the script at the given path and the given parameters (optional) to construct an ExeCommand
:
powershell.exe <parameters> –EncodedCommand <base64-encoded script>
If this proposal is accepted, I would take care of the implementation.
Like your other ticket. Which problem do you have with the WIX template. Your syntax it only usable if understandable WIX syntax.
Can you provide a PR for this topic? I think that it is important for users to know which settings are required and which values are possible. That should be part of the code and we should also put it n the Readme / Wiki.