WiX: The Pain of WiX (Part 2 of 3)

In the first part of this series I gave an introduction to WiX. In this second installment of this three part series, I am assuming that you’ve read through the Windows Installer documentation and through Gábor Deák Jahn’s WiX Tutorial. Additionally, I’m assuming that you’ve written a simple installation using WiX so you’ve read about or used TALLOW.EXE, which is the tool for creating WiX fragments.

If your installation is only three or four files you can create your .WXS file by hand and have no troubles at all. Where things get more difficult is if you are dealing with an application that has hundreds if not thousands of files, and you are adding and removing files during the throes of development. As I mentioned previously, a web application with its myriad of .JPG and other static files suffers from this problem. The prospect of creating a .WXS file, a portion of which is shown below, for thousands of files starts to sound like a three week task of tedious manual editing.


<DirectoryRef Id=”TARGETDIR”>
<Directory Id=”dir_Install_0″ Name=”Install”>
<Component Id=”comp_FOO_INSTALL_0″
DiskId=”1″
KeyPath=”yes”
Guid=”CDCC0AD9-FAB6-4D88-A7CC-F48752F2E4AF”>
<File Id=”file_FOO_INSTALL_0″
Name=”CREATE_1.CMD”
LongName=”CreateMSI.cmd”
src=”.CreateMSI.cmd” />
</Component>
<Component Id=”comp_FOO_INSTALL_1″
DiskId=”1″
KeyPath=”yes”
Guid=”CB8CFE88-069D-4F83-9A25-232DDBC9586A”>
<File Id=”file_FOO_INSTALL_1″
Name=”FIRSTW_1.CMD”
LongName=”FirstWaxRun.cmd”
src=”.FirstWaxRun.cmd” />
</Component>
<Component Id=”comp_WAX_INSTALL_9″
DiskId=”1″
KeyPath=”yes”
Guid=”A669C7B6-9C9D-465D-B292-C8A92379EE43″>
<File Id=”file_FOO_INSTALL_9″
Name=”Install.sln”
src=”.Install.sln” />
</Component>

The good news is that WiX has a tool, TALLOW.EXE, which is designed to get you started by creating a .WXS file for files in a directory, optionally recursing, and putting the files in a nice WiX construct called a fragment, represented by a standalone .WXS file. This allows you to isolate the parts of your installation into separate fragments so when developers need to add or remove files to the installation, they can do so without touching parts they are not responsible for. TALLOW.EXE also has some nice features for reading COM components and .REG files and synthesizing the corresponding information into a .WXS file. If you want to add a custom dialog to your install’s user interface, TALLOW.EXE can read a .RC file produced by Visual Studio’s dialog editor and output the dialog in .WXS format. (Note that for WiX 3.0 TALLOW.EXE has been replaced by a tool called HEAT.EXE.)

While it’s a start, TALLOW.EXE has some serious problems if you have more than five files in your installation. These problems make the whole WiX experience extremely frustrating to anyone attempting to convince their team to switch to WiX, or, if you are using WiX, extremely time consuming and tedious. The first of the problems with TALLOW.EXE, which some would call minor, but I find annoying, is that the .WXS fragments it produces do not compile with all warnings turned on in CANDLE.EXE. I always set any tool I use to the highest warnings possible, because if developers went to the trouble of coding additional error analysis, I feel it’s mandatory to take advantage of that error analysis. All TALLOW.EXE needs to do is put an additional attribute, KeyPath=”yes”, on each Component element to fix this problem.

Another problem with TALLOW.EXE is that it does not have an option to exclude specific files or directories from the output. It works on the idea that the directories and file extensions that you pass on the command line are the only ones you want to include. I think it’s much more common to want to include everything and exclude a few directories and file types. What you end up doing with TALLOW.EXE is generating the .WXS and manually editing out all the files and directories you didn’t want in the first place.

A more serious problem with TALLOW.EXE is that the fragment it produces does not include a ComponentGroup element automatically. A Component element, as I’ll discuss in more detail in a little bit, is one of the most important elements in an installation, because that defines a unit of installation. In most cases that’s a file or group of files in a directory, but it can also include directives to set environment variables, set up SQL Server databases, and so on. In Windows Installer speak, the items associated with a component are called resources. Running TALLOW.EXE on a directory structure of twenty subdirectories will produce a .WXS file with twenty Component elements in it (assuming each of those directories has least one file in them). As you will need to reference those Component elements in your installation, you could add each of the twenty Component elements manually to a particular Feature element, but a better approach would be to add a ComponentGroup element to the TALLOW.EXE-created fragment and include each Component element in a ComponentRef element. That way you isolate the individual component changes to the fragment and just have to reference the ComponentGroup in your main installation .WXS file. The following snippet of a .WXS file shows a ComponentGroup example.


<Fragment>
<ComponentGroup Id=”group_FOO_EXAMPLE”>
<ComponentRef Id=”comp_FOO_EXAMPLE_0″ />
<ComponentRef Id=”comp_FOO_EXAMPLE_1″ />
<ComponentRef Id=”comp_FOO_EXAMPLE_2″ />
<ComponentRef Id=”comp_FOO_EXAMPLE_3″ />
</ComponentGroup>
<DirectoryRef Id=”TARGETDIR”>

As you start looking at doing larger projects with WiX where you may have many files in multiple parallel directories, you’re probably going to be creating a fragment file with TALLOW.EXE for each of the directories. Once you manually add the ComponentGroup elements to the fragments and set up your build to compile all the fragments, you’re going to find that your installation won’t build. The problem is that each Component, Directory, and File element must have a unique Id attribute, and TALLOW.EXE generates identical names for each directory it’s run against. Thus you’ll have to manually edit each of the .WXS fragments and change the Component, Directory, and File element Id attributes to unique names in each of your .WXS fragments.

Another problem with how TALLOW.EXE generates the Component, Directory, and File elements’ Id attributes is shown below:


<Directory Id=”directory1″
Name=”Tests”>
<Component Id=”component1″
DiskId=”1″
Guid=”PUT-GUID-HERE”>
<File Id=”file25″
Name=”Tests.sln”
Source=”C:DevTestsTests.sln” />
</Component>
<Directory Id=”directory2″
Name=”KEYBOA_1″
LongName=”KeyboardTest”>
<Component Id=”component2″
DiskId=”1″
Guid=”PUT-GUID-HERE”>
<File Id=”file26″
Name=”App.ico”
Source=”C:DevTestsKeyboardTestApp.ico” />

If you look closely you’ll see that the Component, Directory and File elements Id attributes are numbered consecutively. What do you think you would have to do if you needed to add an additional file in the Tests directory? You’d have to insert the File element with one value higher than the last Id attribute used in the .WXS file. However, when you start thinking about the real world, and a web application in particular, you can see that this will get to be a maintenance issue quite quickly.

If you haven’t guessed by now, TALLOW.EXE is just enough to get you going with WiX, and after you’ve run it you are completely on your own to manually edit and maintain your installation. When many people realize that they are going to be manually editing .WXS fragments all the time, they decide WiX isn’t worth the effort. As you look through the Source Forge WiX Users mail alias, you will see the constantly recurring theme of developers complaining about manually editing WiX fragments and how it’s driving them away from using WiX.

Fortunately, as you shall see in the next installment of this series, I’ve got a possible solution to avoiding all the manual editing of your .WXS fragments. But if these problems with TALLOW.EXE are fixable, you might be wondering why the WiX development team didn’t extend TALLOW.EXE to solve the issues I pointed out? It’s all about component rules in Windows Installer.

As I mentioned, a component is the key unit of data in Windows Installer and breaking the rules that govern components can lead to installers that don’t install or incorrectly remove parts of your application. The documentation that discusses how to organize your application into components is absolutely vital to understanding all the ins and outs of component rules. There’s also an excellent page on what happens when component rules are broken so you can see exactly how you could break component rules and the consequences. Rob Mensching has an excellent discussion of the component rules as well.

The WiX developers feel that the potential to break component rules is worth avoiding at all costs. They are absolutely right in that regard. However, it’s left us poor developers trying to use WiX struggling with tremendous amounts of manual editing on .WXS fragments when trying to keep our installation code up to date in the middle of development. What I wanted to do was to come up with a program that would eliminate the time drain of manually manipulating .WXS fragments, and with extremely careful use, would make developing installations much simpler.

While parts of WiX can be painful, I definitely feel it’s the best tool out there. In the final installment of this series, I’ll give you a better TALLOW.EXE that should cut the manual time you spend with WiX down from hours at a time to minutes a day.

Edit: Read Part 3 here.

We deliver solutions that accelerate the value of Azure.

Ready to experience the full power of Microsoft Azure?

Start Today

Blog Home

Stay Connected

Upcoming Events

All Events