Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSL-Extension for MSI-embedded (PowerShell-)script? #59

Open
mithomas opened this issue Jun 11, 2018 · 2 comments
Open

DSL-Extension for MSI-embedded (PowerShell-)script? #59

mithomas opened this issue Jun 11, 2018 · 2 comments

Comments

@mithomas
Copy link

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.

@Horcrux7

This comment has been minimized.

@gamma
Copy link
Member

gamma commented Jul 9, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants