Sunday, 25 May 2014

PowerShell Wix Extension

I've looked, but I couldn't find anyone who'd implemented a Wix Extension that would allow running PowerShell scripts. So I've spent a few hours this weekend writing one (and learned a bit more about Wix and MSIs along the way).

This extension allows you to run script from a file that is included in the MSI, or inline script (inside a CDATA section).

By hosting PowerShell in the custom actions, scripts also get access to the $session variable (which is of type Microsoft.Deployment.WindowsInstaller.Session), so you can call $session.Log("Running this") and it will add "Running This" to the MSI log!

Here's an example of what you can do:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:powershell="http://schemas.gardiner.net.au/PowerShellWixExtensionSchema">
  <Product Id="*" Name="PowerShellWixTest" Language="1033" Version="1.0.0.0" Manufacturer="David Gardiner" UpgradeCode="c61298af-d8c9-4179-903f-f42fa69b59ad">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

    <Feature Id="ProductFeature" Title="PowerShellWixTest" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>

    <powershell:File Id="PSFile1" File="[#TestPs1]" Arguments="&quot;First Argument&quot; 2"/>

    <powershell:Script Id="Script2">
      <![CDATA[
        
        # Write-Host "Number 2";
        
        for ($i = 1; $i -le 100; $i++) 
        { 
          Write-Progress -Activity "Activity" -Status "Status $i% complete" -CurrentOperation "Operation $i" -PercentComplete $i
          Start-Sleep -Milliseconds 5 
        }
        
        ]]>
    </powershell:Script>
    
    <UI>
      <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
      <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
      <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />

      <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
      <Property Id="WixUI_Mode" Value="Minimal" />

      <DialogRef Id="ErrorDlg" />
      <DialogRef Id="FatalError" />
      <DialogRef Id="FilesInUse" />
      <DialogRef Id="ProgressDlg2" />
      <DialogRef Id="UserExit" />

      <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

      <Property Id="ARPNOMODIFY" Value="1" />
    </UI>

    <UIRef Id="WixUI_Common" />
  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="PowerShellWixTest" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <Component Id="ProductComponent">
        <File Id="TestPs1" Source="Test.ps1" KeyPath="yes" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

The code and releases are hosted on GitHub - https://github.com/flcdrg/PowerShellWixExtension

Development resources

No comments: