Authoring your first .wxs file

Windows Installer XML (WiX) v3.0

Authoring your first .wxs file

The goal of this tutorial is to help you to get familiar with WiX and the fundmental building blocks in order to build a simple installable .msi package using WiX. We will start with the basic WiX code to create an .msi package that installs one file.

To get started, pick your favorite XML editor (such as Notepad or Visual Studio) and create a new file called product.wxs. Nothing about that name is special, but the .wxs extension lets us know that this is a Windows Installer XML source file. Next, add the three lines of text that all .wxs files must contain:

<?xml version='1.0'?><Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
</Wix>

That forms the outer skeleton for our source file. You can pass this empty source file to candle.exe and get out an empty object file. Tell you what, let's do that. Follow the following steps and you should see very similar output:

C:\test> candle product.wxs
Microsoft (R) Windows Installer Xml Compiler version 1.0.1220.15022
Copyright (C) Microsoft Corporation 2003. All rights reserved


C:\test> type product.wixobj
<?xml version="1.0" encoding="utf-8"?><wixObject 
xmlns="http://schemas.microsoft.com/wix/2003/04/objects"
src="C:\test\product.wxs" />

C:\test>

Notice that when there is no error, Candle doesn't print any text other than its header. In fact, you can even suppress the header output by specifying "-nologo" on the command line. In that case, Candle will print nothing unless there is a failure.

Okay, now that we've seen an empty source file create an empty object file, let's create an installable Windows Installer package. Add the following content to your product.wxs file: p>

<?xml version='1.0'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Product Id='PUT-GUID-HERE' Name='Test Package' Language='1033' 
            Version='1.0.0.0' Manufacturer='Microsoft Corporation' UpgradeCode='PUT-GUID-HERE' >
      <Package Description='My first Windows Installer package'
               Comments='This is my first attempt at creating a Windows Installer database'
               Manufacturer='Microsoft Corporation' InstallerVersion='200' Compressed='yes' />

      <Directory Id='TARGETDIR' Name='SourceDir'>
         <Component Id='MyComponent' Guid='PUT-GUID-HERE' />
      </Directory>

<Feature Id='MyFeature' Title='My 1st Feature' Level='1'> <ComponentRef Id='MyComponent' /> </Feature> </Product>
</Wix>

This will allow you to create an .msi with a ProductCode of "{PUT-GUID-HERE}" with a ProductLanguage of "1033" and a ProductVersion of "1.0.0.0". All of that information is taken from the <Product> element. The <Package> element defines all of the information that goes in our .msi's summary information stream. Finally, a simple <Directory> and <Feature> tree is created with a single <Component>. This is enough to get our .msi registered on the machine.

So let's compile, link, and install, then take a look at the registered packages for our .msi using the following instructions:

Note: This .msi requires administrative privileges in order to install correctly. It will silently fail if you are not installing as an Administrator.

C:\test> candle product.wxs
Microsoft (R) Windows Installer Xml Compiler version 1.0.1220.15022
Copyright (C) Microsoft Corporation 2003. All rights reserved
 
product.wxs
 
C:\test> light product.wixobj
Microsoft (R) Windows Installer Xml Linker version 1.0.1220.15022
Copyright (C) Microsoft Corporation 2003. All rights reserved
 
C:\test> msiexec /i product.msi

You can now go to Add/Remove Programs in the Control Panel and see "Test Package" listed there. At this point, you should go ahead and uninstall the package, so you don't forget it later.

Now that we have an empty .msi that installs and uninstalls properly, let's actually install something. So, create a new text file called readme.txt in the same directory as the product.wxs file and type a message such as "Hello, World!" in the file. Then, we need to modify product.wxs to tell it about the file:

<?xml version='1.0'?><Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Product Id='PUT-GUID-HERE' Name='Test Package' Language='1033'
            Version='1.0.0.0' Manufacturer='Microsoft Corporation' UpgradeCode='PUT-GUID-HERE'>
      <Package Description='My first Windows Installer package'
                Comments='This is my first attempt at creating a Windows Installer database'
                Manufacturer='Microsoft Corporation' InstallerVersion='200' Compressed='yes' />
 
      <Media Id='1' Cabinet='product.cab' EmbedCab='yes' />
 
      <Directory Id='TARGETDIR' Name='SourceDir'>
         <Directory Id='ProgramFilesFolder' Name='PFiles'>
            <Directory Id='MyDir' Name='Test Program'>
               <Component Id='MyComponent' Guid='PUT-GUID-HERE'>
                  <File Id='readme' Name='readme.txt' DiskId='1' Source='readme.txt' />
               </Component>
            </Directory>
         </Directory>
      </Directory>
 
      <Feature Id='MyFeature' Title='My 1st Feature' Level='1'>
         <ComponentRef Id='MyComponent' />
      </Feature>
   </Product>
</Wix>

Now you can compile, link, and install the .msi and see that it creates a directory called "Test Program" in your system's "Program Files" folder. The file readme.txt will be installed in the "Test Program" directory. After verifying that installation works as expected, remember to uninstall the .msi so you can rebuild it and install a new version again later.

That's all there is to creating a Windows Installer package. You can do many more advanced things, such as adding setup UI to your .msi, but we've covered the basics. Everything just comes down to filling in the right XML elements.