Windows installer with WiX 4 - part 1

Building a Windows installer with WiX 4 - part 1
WiX
installers
Author

J-M

Published

March 16, 2023

“WiX logo”

Background

The software stack for streamflow forecasting will be made installable on Windows via an installer, with code signing. There are multiple motivations for this, some of it is perceptions and first impressions for new users. More importantly code signing and managed installation are particularly important for some users in an operational environment (hydro-electric production, water management).

I used to produce installable .NET applications way back, but I’ve lost sight of where the state of play is these days. Besides, the stack is not .NET, so it is sime to revisit the field.

Quick review and resources

One list of available installation software is via Wikipedia list of installation software. Paid options may be in scope if this brings value, but I’ll first cover open source or “freeware” types. Prior to this port and a priori I considered:

  • Orca seems to be the successor of what I used to use (Windows Installer) from Visual Studio way back.
  • WiX is a FOSS option, and version 4 has release candidates as I write.
  • The venerable Innosetup.
  • NSIS is also a possible candidate. I think the NSIS option was what I previously used under the hood of what electron-builder, see this previous blog post for context, but I may be wrong about that.

I am partial to trying WiX for this and follow-up post. This is one of the non-proprietary options that produces a Windows Installer.

WiX

Version 3 of the WiX toolset is mostly documented as of March 2023, V4 is understanbly not as well documented. Notwithing this I was still looking for “cheap” options, i.e. adapting from a suitable template, but did not find this kind of resource in the WiX doc. A very good third party resource I found is WiX Installer Examples. It is based in WiX 3 for now, but a resource I am likely to look at even if I trial WiX version 4.

A useful resource to get acquainted with WiX 4, as I write, is a playlist of coding dojos (note that episodes are in reverse chronological order) by the lead developer of WiX, Rob Mensching. The code repository used for the successive sessions may be here. Note that as these videos were posted weekly, WiX 4 was in preview, so expect that some things there may change, and have changed as we’ll see below.

There are new project templates in a Visual Studio extension Heatwave, by FireGiant, but for this first post I will probably stick to manually crafting the files. Nevertheless, installing the extension brings some intellisense goodness to Visual Studio, so if you have VS you should install the Heatwave extension.

For subsequent posts not this present one: we will likely use the WiX doc section on code signing for WiX, albeit for version 3. Also, requested a certificate via digicert using this procedure. Note the key length is 3K minimum now.

Walkthrough

This part one will be the first baby step. While fundamental concepts in installers are not intrinsically complex, I’m scarred enough to appreciate their complicated nature.

Let’s adapt a simple installer as per the dojos, and get one of our compiled software libraries copied. The final installer may look very different (project dependencies, file groups, etc.), but this is a few posts down the track.

Windows Sandbox

The dojo playlist has an episode on Building a windows sandbox. I did not know about this, and this sounds like a very good idea. I will only give the essential steps, checking the video gives more information. Following the Windows Sandbox MS doc:

in PowerShell as Administrator :

Warning

CAUTION: the following powershell admin command below may reboot your machine without asking permission.

Enable-WindowsOptionalFeature -FeatureName "Containers-DisposableClientVM" -All -Online

Then as per the Building a windows sandbox video, setting up a Windows sandbox file and adapting a little bit the DeploymentDojo/BeltTest to my context.

<Configuration>
  <MappedFolders>
    <MappedFolder>
      <HostFolder>C:\src\sffs-docs</HostFolder>
      <SandboxFolder>C:\dojo</SandboxFolder>
    </MappedFolder>
  </MappedFolders>
  <LogonCommand>
    <Command>C:\dojo\wip\dojostart.cmd</Command>
  </LogonCommand>
</Configuration>

The cmd file has the very same content as the github repo:

start appwiz.cpl
start "" "C:\dojo"
start "" "C:\Program Files (x86)"
@ rem start regedit

.\dojo.wsb works fine.

Step 1

Starting from the wsx file in Rob’s dojo video to adapt to my context:

<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
  <Package Name="SF" Manufacturer="CSIRO" Version="0.1" UpgradeCode="2e7d7f1d-1111-1111-1111-b363c7ce3a1e">
    <MajorUpgrade DowngradeErrorMessage="A newer version was detected"/>
    <Feature Id="All">
      <Component Directory="InstallFolder">
        <File Source="C:\local\libs\64\swift.dll"/>
      </Component>
    </Feature>
  </Package>
  <StandardDirectory Id="ProgramFilesFolder">
    <Directory Id="InstallFolder" Name="SF">
    </Directory>
  </StandardDirectory>
</Wix>

wix build .\sf.wxs

error WIX0005: The Wix element contains an unexpected child element ‘StandardDirectory’.

On a hunch after looking at a subsequent version of the code github repo, I reckon I should try to put the StandardDirectory block inside a Fragment. No squigly line anymore in Visual Studio is a good sign.

Then I finally notice that actually I had the </Fragment> in the wrong spot. So either:

<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
  <Package Name="SF" Manufacturer="CSIRO" Version="0.1" UpgradeCode="2e7d7f1d-8a18-47ea-ae43-b363c7ce3a1e">
    <MajorUpgrade DowngradeErrorMessage="A newer version was detected"/>
    <Feature Id="All">
      <Component Directory="InstallFolder">
        <File Source="C:\local\libs\64\swift.dll"/>
      </Component>
    </Feature>
  </Package>
  <Fragment>
    <StandardDirectory Id="ProgramFilesFolder">
      <Directory Id="InstallFolder" Name="SF">
    </Directory>
  </StandardDirectory>
  </Fragment>
</Wix>

or more logical for a single XML file package definition:

<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
  <Package Name="SF" Manufacturer="CSIRO" Version="0.1" UpgradeCode="2e7d7f1d-8a18-47ea-ae43-b363c7ce3a1e">
    <MajorUpgrade DowngradeErrorMessage="A newer version was detected"/>
    <Feature Id="All">
      <Component Directory="InstallFolder">
        <File Source="C:\local\libs\64\swift.dll"/>
      </Component>
    </Feature>
    <StandardDirectory Id="ProgramFilesFolder">
      <Directory Id="InstallFolder" Name="SF">
      </Directory>
    </StandardDirectory>
  </Package>
</Wix>

and yes now it builds. At least I have an inkling of the use of Fragment elements in multiple files.

Warning

Note: I first launched the “Add or Remove Programs” in the sandbox to check the app installation. But it did not show the installed application, with a continuous spinning wheel. You need to open the older interface with appwiz.cpl (as in the startup batch file)

Conclusion

So far so good for baby step 1. To be continued in part 2.