Introduction

This article is intended as an absolute beginner's introduction to Wix and Votive.

Wix is the Windows Installer XML, an open source project under the Common Public License. In essence, it is a toolset that builds Windows installation packages from XML files. The current stable version is v2, but version 3 is eminently usable. Version three does suffer from a lack of documentation, frequently forcing the user to search for help.

Votive is a plug-in for Wix that integrates the Wix project type with Visual studio, allowing you to work entirely within the IDE when building your installer.

Visual Studio 2008 is the latest version of Microsoft's excellent IDE. The procedures outlined below should also work in Visual Studio 2005. The examples in this article are built against version 3.5 of the .NET framework, but should all work unchanged against version 2 upwards.

In order to follow this tutorial, you will need to download and install Wix from Sourceforge.net. Select the latest directory. Sources and other downloads are available in the same location, but for our purposes, we need Wix3.msi. This will install both Wix and Votive.

Creating a simple application to be the target for installation.

An installer is pretty worthless without something to install. In this instance, we are going to create a basic Windows Forms Application to be our installation target. Fire up Visual Studio, select File -> New -> Project. Select Windows Forms Application, call it InstallationTarget, and select an appropriate destination for the solution (I used C:\Development\Wix Tutorial).

Rename Form1 to frmCongratulations, and add a Label to the form. Set the text to be "Congratulations, application installed successfully".

Build the application. It should look something like this:

And that's us, as far as building our installation candidate is concerned. We'll move on to the installer itself.

Add an installer project

Click File -> Add New Project. If you've installed Wix correctly, you will have a Wix option under project types. Select this option. Under the Visual Studio Installed Templates, select Wix Project, change the name to ExampleInstaller, and set the appropriate location.

This will create a Wix project in your solution. The solution consists of:

ExampleInstaller.wixproj, the project file.

ExampleInstaller.wxs, a basic Wix XML file. This is the file that the Wix binaries use to build the installation package.

A word about the Wix binaries

"Under the hood", a Wix Visual Studio project uses a number of binaries to build the installation packages defined in the project XML files. Candle is the compiler, Light is the linker. There is also a library tool (lit) and a decompiler (Dark). These tools are available from the command line (indeed, before Votive, they were only available from the command line). Both the Compiler and Linker have their own property tabs in the Wix project properties page.

Building our installer

At this point, we can accept the default project settings generated by Votive, and examine the XML file that has been generated for us.

The Product element is our "main" element, and is essentially what will go into the final MSI. Only one Product element can be specified per installer. It requires a unique GUID (automatically generated when the file is created), a decimal language ID (LCID, defaults to Unites States English, 1033; the UK LCID is 2057), and an upgrade code, which is another automatically generated GUID. Also required are the product's name, manufacturer, and version.

The Package element contains properties about the package. These properties can be seen in Explorer when examining the installer package.

The Media element can be left as is. It describes the installation media for the installer. Votive will automatically name the cabinet file for the installer to the name of the installer project, and set the value for "EmbedCab" to yes. Unsurprisingly, this leads to the installer containing a cabinet called "ExampleInstaller.cab". If the Cabinet and EmbedCab attributes are removed, the source files are untouched, and must be delivered with the MSI for installation to take place. The media ID is used internally by the Media table of the installer, and that's all the information I could find on it, other than that the value should be greater than or equal to 1. For our purposes, we can leave it at 1.

A group of Directory elements are declared. The outermost, with the "TARGETDIR" attribute, is a virtual dir, used to contain the other Directory elements which describe the directory structure for the installation. The second element is a standard Windows installer directory. The final Directory element is the installation location. We need to change the Name attribute to the name of the directory in which we want to install our application.

Within the installation Directory element is a Component element. A component is a logical grouping of resources that are to be placed together. This is where we will add our application to the Wix file.

The Feature element describes an installable element. There may be one or more Features, and each Feature must contain one or more Components.

Customizing the .wxs file

The pre-generated wxs file provides us with a nice template. We'll start by configuring the values that the template hasn't done for us.

Product

Name: Change to "Wix installer walkthrough"

Manufacturer: Change to "Duncan Lundie"

Directory

In the Directory element with the "INSTALLLOCATION" ID, change the Name attribute value to "Installer Example"

Feature

Change the Title attribute value to "Installation Target"

That's the basics done, but it still won't install anything. In order to have it install the output of our example application, we need to add the following element to the Component element that we have already defined.

As you might infer from the element's name, this introduces a file to the installer. The ID is the name that will be given to the file when it is installed (it need not be the name of the source file) and Source is the full path to the output of our example application. A build will fail if the Source specified is not found.

Build the solution (Ctrl+Shift+B). Assuming that everything builds OK, you will be left with ExampleInstaller.msi in your Wix project's output directory. Try running this now. What you should see (briefly) is this:

When the installer finishes, you should be left with a file called InstallationTarget.exe in C:\Program Files\Installer Example.

Congratulations, you've built your first installer with Wix. This installer is incredibly simplistic, and makes use of only the most basic elements (pun intended) of Wix, but it should give you a flavor of how Wix works.

A word about project outputs

As you've seen from the example above, Wix takes a fixed path as the Source value for a File element. There is no equivalent to a standard setup project's "Primary Project Output" target. How then do we cope with a change in build type? How do we cope when we want to create a release version of both the target and the installer? Thankfully, we have a mechanism to do this, we use a Compiler constant, imaginatively called BUILD. Open the property pages for your Wix project, and select the Compiler tab:

In the "Define constants" textbox, add BUILD=Debug, and then save your settings. Now, change your VS2008 configuration to Release. You will notice that the constant you defined has vanished; this is because the constants are defined per configuration. Add BUILD=Release to the "Define constants" textbox.

We can now refer to this constant in our Wix XML. We do this with the notation: $(var.NAMEOFVARIABLEORCONSTANT).

We can change the Source of our File element to Source="../InstallationTarget/InstallationTarget/bin/$(var.BUILD)/InstallationTarget.exe".

When Wix is built, it will replace the placeholder with the appropriate value, and therefore grab the appropriate version of your application for the build configuration.

Nice introductory write-up Duncan. I've run through this in vs2010 using wix 3.6 and though as you would expect there are some changes to both the xml and screen shots, it's still a decent place to start.

There are many subtilties to this scripting and it's easy to make a mistake. It would be most helpful if someone could post a complete script to serve as a SIMPLE example for those of us who are rank beginners.

For example, here's my script (VS 2010, WIX 3.5 toolkit)

<?xmlversion="1.0"encoding="UTF-8"?><Wixxmlns="http://schemas.microsoft.com/wix/2006/wi"><ProductId="185b7179-5a67-46ce-bbab-a2094e88e20c"Name="Wix installer walkthrough"Language="1033"Version="1.0.0.0"Manufacturer="Duncan Lundie"UpgradeCode="4700762e-f178-43a7-871d-9fe671c977c3"><PackageInstallerVersion="200"Compressed="yes"/><MediaId="1"Cabinet="media1.cab"EmbedCab="yes"/><DirectoryId="TARGETDIR"Name="SourceDir"><DirectoryId="ProgramFilesFolder"><DirectoryId="INSTALLLOCATION"Name="InstallerExample"><!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --><!-- <Component Id="ProductComponent" Guid="b4346add-4a60-444c-aa02-cdeab7f578ef"> --><!-- TODO: Insert files, registry keys, and other resources here. --><!-- </Component> --><ComponentId="ProductComponent"Guid="b4346add-4a60-444c-aa02-cdeab7f578ef"><FileId="InstallationTarget.exe"Source="../InstallationTarget/InstallationTarget/bin/debug/InstallationTarget.exe"></File></Component></Directory></Directory></Directory><FeatureId="ProductFeature"Title="Installation Target"Level="1"><!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. --><!-- <ComponentRef Id="ProductComponent" /> --><!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. --><ComponentGroupRefId="Product.Generated"/></Feature></Product></Wix>

Compiler Error: ICE21: Component: 'ProductComponent' does not belong to any Feature.

WTF does that mean ?

OK, I solved that problem - WITHOUT DOCUMENTATION !!

Well, alright, it's in the script comments but not very clear:

'Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer.'

<?xmlversion="1.0"encoding="UTF-8"?><Wixxmlns="http://schemas.microsoft.com/wix/2006/wi"><ProductId="185b7179-5a67-46ce-bbab-a2094e88e20c"Name="Wix installer walkthrough"Language="1033"Version="1.0.0.0"Manufacturer="Duncan Lundie"UpgradeCode="4700762e-f178-43a7-871d-9fe671c977c3"><PackageInstallerVersion="200"Compressed="yes"/><MediaId="1"Cabinet="media1.cab"EmbedCab="yes"/><DirectoryId="TARGETDIR"Name="SourceDir"><DirectoryId="ProgramFilesFolder"><DirectoryId="INSTALLLOCATION"Name="InstallerExample"><!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --><!-- <Component Id="ProductComponent" Guid="b4346add-4a60-444c-aa02-cdeab7f578ef"> --><!-- TODO: Insert files, registry keys, and other resources here. --><!-- </Component> --><ComponentId="ProductComponent"Guid="b4346add-4a60-444c-aa02-cdeab7f578ef"><FileId="InstallationTarget.exe"Source="../InstallationTarget/InstallationTarget/bin/debug/InstallationTarget.exe"></File></Component></Directory></Directory></Directory><FeatureId="ProductFeature"Title="Installation Target"Level="1"><!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. --><!-- <ComponentRef Id="ProductComponent" /> --><ComponentRefId="ProductComponent"/><!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. --><ComponentGroupRefId="Product.Generated"/></Feature></Product></Wix>

I have installed Wix 3.5 on my Windows 7 machine (32/64-bit) using Visual Studio 2010. Despite all the praises for WIX, I find it quite cumbersome to use, and far prefer my older Windows Setup Project. If there is a GUI (that's what I thought Votive was), it's not apparent. That means that I have to hand edit the Product.wsx file which I find most distasteful, particularly since it shouldn't be much of a problem to program a GUI to do it.

If I attempt to add the Reference Votive2010.dll, it cannot be added to VS 2010.

I am really puzzled as to all the fuss about WIX. Doing things like custom icons, shortcuts, custom license and readme files, which are easy to accomplish using Visual Studio Installer, are excruciatingly complicated using WIX. In short, I think WIX is another SourceForge boondoggle.

BTW, your sample installer will not compile on Win7 / VS2010 / WIX. Specifically, it doesn't allow access to candle.exe file. There are a whole bunch of WIX blogs on this issue, none of which are comprehensible to me, and no workarounds.

Edit (10.25.2012): Came back to this because I like the look of the installer once it's created. As to the file access to candle.exe (and for that matter all of the other Wix tools), it turns out that the culprit is the <wixtoolpath> ... in the *.wixproj file. This needs to be edited to match your machine installation path -- it is not automatically done when installing the wix tool set. There are alot of other quirky things about Wix. After installing the Wix Tool Kit, Visual Studion shows under New Project 'Windows Installer XML' under the C++ heading. But the program is actually a C# program - a small matter that calls into question the care with which this AddOn has been crafted. Adding your own background and banner and customized License Agreement seems simple enough - just place them in the project directory and add them to the project. But nowhere do I find a reference to these in the script. These are called : banner.bmp, bigback.bmp, and GPL3.rtf respectively and in the sample WixGUIInstaller sample, they just work. I have yet to figure out how to add shortcuts to the Start menu and Desktop.

I just finished going through this exercise and found it very helpful to get me started with WiX. You got a 5 from me.

I'm using the following tools:
Visual Studio 2010 Pro
WiX 3.5
WixEdit

Votive has changed a little since 2007. I found WixEdit to be a very nice GUI for the wxs file. It does not integrate with VS, but you can assoicate it with the .wxs type so it opens by default.

I have a work project which requires me to create an installer that can install a Windows Service multiple times on the same machine -- each instance connecting to a difference database that I need to enter during installation. And each instance connecting to a WCF Servce URL that must be entered during installation. So, I will need a custom UI as well. I found another tool that looks really nice named SharpSetup that also integrates with VS and uses WiX. This allows creation of the UI in .NET. But it provides little help understanding how to use the WiX project. I'll be going through your Part 2 article shortly.

Good Introduction to this alternative method of producing an MSI installer package. Does provide illumination on subjects such as definition of WiX Variables, Sadly overlooked and not properly documented with respect to the Votive installation.

I have been trying to get to grips with Click Once which is great for .Net applications but not so for native C++ apps. WiX may be the solution I am looking for.

Great article btw. Quick, to the point and a great "Hello World" success.

One question though with regards to the BUILD variable that you mentioned... I have VS2005 Wix v3 and don't seem to have that tab (compile) as you show it - but I think you used VS2008? Anyway, I substituted $(var.Configuration) and I received the same results as your BUILD variable. This seems to work and was wondering why this BUILD var was needed.

I went to SourceForge and took a quick glance over the feature set. This looks like a great tool. Besides being able to define installers in XML, what advantages does this have over the built-in installers?

You answered your question yourself, "...whenever I build the solution" is obviously not automated With the built-in deployment projects you always have to have VS installed on your build or integration test servers, which build your software automatically using build scripts e.g. after a user commits changes. Furthermore, from those scripts you have to invoke devenv to "automate", which eats up a whole lot of CPU just to start and shutdown without having built a bit yet.

MSBuild compatible means that you only require the .Net framework because MSBuild technology is integrated in there. No heavy process to start, and just as when working within VS it resolves project dependencies (which again is a great advantage over the old NAnt C# build tasks).