Monday, August 23, 2010

Creating a localized Windows Installer & bootstrapper

This series of articles is a complete end-to-end solution for building a localizable Windows Installer & Bootstrapper using some real-world requirements.
Part 1: Introduction & Setup
Part 2: Defining Conditions
Part 3: Localization
Part 4: Provision Prerequisites
Download WixWindowsInstallerDemo - 1.44 MB
Introduction
It's been a while still my last article so I thought I'd write about my recent experiences with Wix for creating Windows Installer packages. I last used Wix 1.0 about 4 years ago with great results and had forgotten how satisfying it is to use. Unfortunately at the time of writing Wix 3.5 isn't out, but it sounds like there are some great additions in the pipeline including the much anticipated Burn utility (a bootstrap compiler), as well as Votive support for Visual Studio 2010.
In this series of articles I want to provide a complete end-to-end solution for deploying a .NET application based on my recent experiences. The solution provided is based around the following real-world requirements:
Provide a MSI installer which deploys a .NET application
Use NGen to pre-cache .NET assemblies for faster start-up times
Only allow the installer to run on a specific OS
Only allow the installer to run based on the results of an WMI lookup
Only allow the installer to run if prerequisites are installed (.NET 4.0)
Inject version info and other specifics into the installer from a build script
Provide localized versions within a single MSI installer and auto detect the user language
Create a localized bootstrapper as a single file that installs the necessary prerequisites (.NET 4.0)
Note because in my example I'm targeting a Visual Studio 2010 project which isn't supported by the Wix 3.0's Votive project, I'm instead using a NAnt script to automate the build process.
Technology Stack
Wix 3.0
dotNetInstaller 2.0
NAnt 0.90
Note about GUIDs
It's important to generate your own GUIDs when working with Wix to avoid conflicts with other products. As it's common to copy & paste examples, I've deliberately masked my GUIDs to prevent any duplicates ending up in production code. To work with any of the examples in the solution, be sure to replace all ids of the format NEWGUID-XXXX-XXXX-XXXX-XXXXXXXXXXXX with your own unique GUIDS. You'll find these have been factored into Config.Wsi for convenience.
Solution Overview
The MSI installer and EXE bootstrapper are produced from a single NAnt script. The script performs the following steps which are described in more detail throughout this series of articles. To build the project execute the included build.bat file.
Use HEAT to produce a Wix component fragment
Transform HEAT output to inject NGen elements
Use CANDLE to compile the Wix project, injecting build variables
Use LIGHT linker to generate an English version of the MSI
Use LIGHT linker to generate a language variation of the MSI
Use TORCH to create a transform (delta) file by comparing the output of steps 4 & 5
Use WISUBSTG.VBS to embed the MST into the original MSI file
Repeat steps 5-7 for each language supported
Pre-process the dotNetInstaller config file to inject build parameters
Compile the bootstrapper
Read more: Codeproject Part 1, Part 2, Part 3, Part 4