Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Creating an installer using Wix v3.0, Votive, and Visual Studio 2005/2008

4.64/5 (37 votes)
26 Nov 2007CPL7 min read 1   1.5K  
An introduction to creating a Wix installer using Visual Studio 2005/2008.

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).

New c# windows project form

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:

Example application main form

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.

Wix project template form

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.

XML
<?xml version="1.0" encoding="UTF-8"?>
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="07cdd126-8d87-46cf-87b0-8731980619fa"
     Name="PUT-PRODUCT-NAME-HERE" Language="1033"
     Version="1.0.0.0" Manufacturer="PUT-COMPANY-NAME-HERE"
     UpgradeCode="4b2952e6-8ce6-4254-9796-aa510afe5fc0">
   <Package InstallerVersion="200" Compressed="yes" />

   <Media Id="1" Cabinet="ExampleInstaller.cab" EmbedCab="yes" />
   <Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
     <Directory Id="INSTALLLOCATION" Name="PUT-APPLICATION-DIRECTORY-HERE">

      <Component Id="ProductComponent" Guid="17e13748-8d44-47f6-b020-66d29f8a84fe">
       <!-- TODO: Insert your files, registry keys, and other resources here. -->
      </Component>

     </Directory>
    </Directory>
   </Directory>

   <Feature Id="ProductFeature" Title="PUT-FEATURE-TITLE-HERE" Level="1">
    <ComponentRef Id="ProductComponent" />
   </Feature>
  </Product>
 </Wix>

The first line is the standard XML declaration.

The Wix element is the root element of any Wix installer. It declares the appropriate XML namespace.

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.

XML
<File Id="InstallationTarget.exe" 
  Source="../InstallationTarget/InstallationTarget/bin/debug/InstallationTarget.exe"></File>

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:

Installer running

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:

Compiler property 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.

Now that you've created a basic installer, it's time to add a GUI.

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)