Windows Installer XML (WiX) tutorial

From Optimal BPM
Jump to: navigation, search


About this article

This tutorial(or perhaps pre-overview or guide) is a supposedly easy-to-understand overview of the WiX (Windows Installer XML) toolset.
It contains what the author would have liked to have known before plowing through the actual tutorial, which is some pretty heavy reading.
Also, it contains some gotcha's and explains a way to make a WiX installer that the "official" Heat-tool is not capable of. Here Paraffin is used instead.

WiX is declarative, sort of, and what that means

Elsewhere, a lot of emphasis is put on WiX being declarative, this article won't but will explain it anyway.
For WiX, declarative means that The WiX .wxs-files describes how stuff should look when the installation is done. Not how to get there.

Implicitly, this means that when you build an .msi-package with WiX, you don't describe how the installation should be done.

The reasons for this are that the windows installer framework wants to be able:

  • to make its own decisions about how installation should be done.
  • to install the application in such a way that it can uninstall it in a way it finds acceptable.

However, this isn't always, and actually not very always at all, true.

Custom actions, as manual steps are called, will sometimes have to be defined. To be *really* honest, most of the time. :-)


The workflow to generate an .msi-file is:

  1. create .wxs-files manually or using paraffin.exe
  2. compile/syntax check using candle.exe
  3. link/create .msi using light.exe

Creating the .wxs-files - manually/Paraffin

.wxs-files are XML-files that defines how you want things to look when the application is installed.

Specified within these files are(for example):

  • the product(Optimal BPM Tools)
  • features(Optimal BPM Tools, Examples)
  • directories(program files\Optimal BPM\bin\ ..)
  • shortcuts(start menu items)
  • icons,banners and other pretty stuff
  • UI-aspects

Unless your application only contains one or two files, you will likely wind up with at least *two* .wxs-files, one for the installation settings, and one for the files involved.
This tutorial doesn't get into the authoring of the main .wxs-file for now(the official tutorial covers that part pretty well).

These are the ones of the Optimal BPM Tools project(an early version of the installer):

  • optimalbpm-tools.wxs - The main configuration file
  • optimalbpm-tools_files.wxs - A list of all the files that belong to the installation
  • optimalbpm-tools_examples.wxs - A list of all the files included in the examples

All files referenced in this "tutorial" can be found here:

The problem with Heat and why Paraffin

In this project, the first two files (optimalbpm-tools_files.wxs and optimalbpm-tools_examples.wxs) are lists of files that belong to the
different installation options; "Optimal BPM Tools" and "Examples".

Now, if you have lots of files, creating these files by hand could take a pretty long time. To handle that, a tool called "Heat" was created.
One tells the tool what files should be included and the tool collects the files from directories, sets GUIDs and so on.

However, for some inexplicable reason, Heat stops there. When the file is created, the tool no longer serves a purpose.
This is a problem. Since ones project hopefully will live longer, more releases will have to be generated.
Maintaining the wxs-files will then become a continuous thing to remember. When adding a file, a .wxf-file entry has to be added.

Of course, to include manual steps in the development process for no particular reason is pointless, and so, a tool that does all that Heat does,
while also helping with the maintenance of the files, keeps them up-to-date, adds new files, have regex file exclusion, and so on, was developed: Paraffin.

Below is how the optimalbpm_files.wxs is built. I use the full path to the tool, as Paraffin doesn't really have an installer for non-.Net/Visual Studio users. Luckily, they bundle a binary in the \Debug\-subfolder:

C:\Program Files\Paraffin\Debug\paraffin -d "../../sources/optimalbpm/tools" -gn optimalbpm_tools_files
                           -alias "../../sources/optimalbpm/"  optimalbpm_files.wxs -rex ".*___pycache__.*" -rex ".*examples.*"

I can then change all names to what I want, paraffin will compare the file names, keep my changes and only add files.

Paraffin is really a much more usable tool than heat.exe, I would strongly advise against using Heat.

Compilation/Syntax check - Candle

When one has created the .wxs-files, the next step is running candle.exe. Candle is a part of the WiX toolset.

It compiles the content of the .wsx-files into .wixobj-files. It is in this step you get syntax error and the like.

It is simple, it is run by specifying the filenames:

candle optimalbpm-tools_files.wxs optimalbpm-tools_examples.wxs optimalbpm-tools.wxs

It could be noted that even though the .wxs-files are XML-files, the other files are NOT referenced using include-statements in XML.
Instead, the names in the other files can be referenced anyway, since the candle and light tools import them all into the same namespace.
So don't use conflicting names in the files, consider them one big file.

Linking/Packaging - Light

Quoting Wikipedia's good explanation: "Light takes one or more object files and links the references in the object files to the appropriate symbols in other object files.
Light is responsible for collecting all of the binaries, packaging them appropriately, and generating the final MSI or MSM file.".

There is an important point to be made here; in WiX, files aren't included using XML includes or something like that.
All files fed to Light will be included implicitly.

This is how it is run in this case:

light optimalbpm-tools_files.wixobj optimalbpm-tools_examples.wixobj optimalbpm-tools.wixobj -o optimalbpm-tools.msi -ext WixUIExtension
  • If it has only one .wixobj-file as input, it defaults to naming the .msi file to that name.
  • However, here there is more than one .wixobj and therefore needed to specify the "-o"-parameter, to explicitly tell it what the output should be called.
  • Finally, to get an UI, the WixUIExtension is included

If you will only need to make start menu(or whatever windows 8 calls it)-shortcuts to exe-files and want the default application to launch for all links, you can jump to the Scripting the entire process-section now. If not, look at the next section.

Scripting the entire process

Make it simple. Check out the script in the

It is a small python script for the entire process, with some tricks in it. Not very beautiful, but working. Perhaps there'll be a generalized version some day.

Common errors and what to do

Light.exe errors/warnings

LGHT1076 : ICE69: Mismatched component reference. Entry....

Ignore if you know what is it refers to. It is almost impossible to make shortcuts to non-advertized files without causing this, because of WiX:s component integrity.
Doesn't matter if it's within the same feature.

Now would be good time to go read the official WiX tutorial. :-)

Further reading

Scripting languages(Python/Ruby/PHP/Perl etc.)

For a more advanced topic, specifically about issues when installing applications made using scripting languages like Python/Ruby/PHP/Perl or whatever, see the WiX and scripting languages-article.

And even further down that line, if you have pip packages that need to be built using vcvarsall.bat (as you are unlikely to have Visual Studio in production environments) to install properly, there is an article here on that subject: Python packages from exe to WiX to .msi.


In the future, a section describing Burn will be added. Burn is a executable program(.exe, not .msi) that acts as a launcher of the installation and allows sections of the installation to be packed into the install file or downloaded when needed.
It is pretty usable "when you know how it works". However, using it is sometimes not as easy as the tutorial makes it appear. Anyway, that is for later.

Personal tools