WiX installer with PowerShell scripts

WiX is used to create installers. This tool is integrated into visual studio and can be used in any build process or for automatic deployment. No matter how good you software is, if you don’t have a good release/deployment process, you will reduce your client satisfaction and have extra costs for each deployment.

This is a simple example of a WiX installer which copies all selected files to a defined folder and then executes a simple power shell script. When uninstalling, a second script is then executed.

First a simple console application (our software project to be deployed) is required. For simplicity, the 2 power shell scripts are included in this deployment. The project is deployed using a simple harvest. For the power shell script, a custom action is used.

    <!-- My custom actions  install scripts-->
    <CustomAction Id="RegisterPSCmd"
	Property="RegisterPowerShellProperty"
	Value="&quot;C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe&quot; -NoLogo -NonInteractive -InputFormat None -NoProfile -File &quot;C:\damienbod\SimpleConsoleApp\CreateDirectoryAndFilesInstall.ps1&quot; &quot;arg_that_I_maybe_require_for_my_script&quot;"
	Execute="immediate" />

    <CustomAction Id="RegisterPSCmdUninstall"
	Property="RegisterPowerShellPropertyUninstall"
	Value="&quot;C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe&quot; -NoLogo -NonInteractive -InputFormat None -NoProfile -File &quot;C:\damienbod\SimpleConsoleApp\CreateDirectoryAndFilesUninstall.ps1&quot; &quot;arg_that_I_maybe_require_for_my_unistallscript&quot;"
	Execute="immediate" />

    <CustomAction Id="RegisterPowerShellProperty"
	BinaryKey="WixCA"
	DllEntry="CAQuietExec64"
	Execute="deferred"
	Return="check"
	Impersonate="no" />

    <CustomAction Id="RegisterPowerShellPropertyUninstall"
	BinaryKey="WixCA"
	DllEntry="CAQuietExec64"
	Execute="deferred"
	Return="check"
	Impersonate="no" />

The custom actions are added to the InstallExecuteSequence.

  <InstallExecuteSequence>
      <Custom Action="RegisterPSCmd" After="CostFinalize">NOT  Installed</Custom>
      <Custom Action="RegisterPowerShellProperty" After="InstallFiles">NOT Installed</Custom>
      <Custom Action='RegisterPSCmdUninstall' Before='CostInitialize'>(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
      <Custom Action='RegisterPowerShellPropertyUninstall' Before='RemoveFiles'>(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
    </InstallExecuteSequence>

This xml configuration has a important attribute and also an important value. The attribute defines at what stage the custom actions are to be executed and the value defines in what procedure.

Here’s a list of possible values for the attribute (in the execution order) This condition can be defined using a before or after attribute:

  1. AppSearch
  2. LaunchConditions
  3. ValidateProductID
  4. CostInitialize
  5. FileCost
  6. CostFinalize
  7. InstallValidate
  8. InstallInitialize
  9. ProcessComponents
  10. UnpublishFeatures
  11. RemoveShortcuts
  12. RemoveFiles
  13. InstallFiles
  14. CreateShortcuts
  15. RegisterUser
  16. RegisterProduct
  17. PublishFeatures
  18. PublishProduct
  19. InstallFinalize
  20. RemoveExistingProducts

The procedure when the custom action is to be executed is defined in the value. This post explains the possible values:
http://stackoverflow.com/questions/320921/how-to-add-a-wix-custom-action-that-happens-only-on-uninstall-via-msi

Here’s a picture taken from the link:
installProcedure

After the msi has been installed and then uninstalled, 2 scripts are created:
Deployment

This is just a demo, but these scripts could do almost anything to you operating system.

One problem is that if the power shell script execution is not enabled, the installer won’t work.

To check your execution policy, open the power shell and type Get-ExecutionPolicy. The result needs to be RemoteSigned or Unrestricted

Possible values are:

  1. Restricted – No scripts can be run. Windows PowerShell can be used only in interactive mode.
  2. AllSigned – Only scripts signed by a trusted publisher can be run.
  3. RemoteSigned – Downloaded scripts must be signed by a trusted publisher before they can be run.
  4. Unrestricted – No restrictions; all Windows PowerShell scripts can be run.

If not, enter Set-ExecutionPolicy RemoteSigned and Y
psScriptPolicy

Here’s a full working example.
Code: https://github.com/damienbod/WiXPowerShellExample

Links

http://wix.tramontana.co.hu/tutorial/events-and-actions/queueing-up

http://stackoverflow.com/questions/320921/how-to-add-a-wix-custom-action-that-happens-only-on-uninstall-via-msi

http://wixtoolset.org/

http://wix.sourceforge.net/manual-wix3/main.htm

http://technet.microsoft.com/en-us/library/ee176847.aspx

3 comments

  1. Wonderful explanation. Thank you so much for sharing your knowledge.
    value engineering services

  2. Marek · · Reply

    You can set the ExecutenPolicy as an Attribute in your Custom Action:

    -ExecutionPolicy RemoteSigned

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: