Getting started
Here is what you need first:
1) On Windows XP you might need to download and install the
Microsoft .NET Framework if you have none installed on your PC. The WiX toolset requires the .NET Framework, currently this is version 3.5 SP1. The installation takes some time, time to get a coffee.
2) Download and install the following file:
WiX Toolset v3.0. WiX is a collection of free tools that builds software installers from XML documents.
You can build an installer from command line, but also use an IDE such as Visual Studio or Eclipse. Let's have a look at the tools and create an MSI file from command line.
Create your first WiX file
Create an XML file
example.wxs
as below:
="1.0"
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
</Wix>
That's the absolutely minimum, let's add a little bit more:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111"
Name="Example Product Name" Version="0.0.1" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222"/>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
</Feature>
</Product>
</Wix>
Create your first MSI installer
Create a batch file
make_installer.bat
as below:
candle example.wxs
light example.wixobj
@pause
Run it to build the package, ignore any warnings. In case you are curious:
candle
is the WiX compiler (generates an object file),
light
is the WiX Linker (generates the final installer).
There will be an
example.msi
in your folder now, congratulations! Double click it to install it, then go to Add/Remove Programs in the Control Panel where you can find an "
Example Product Name
". Don't forget to uninstall it, so you can later build and install a new MSI file.
Create a simple application installer
Copy an application into the same directory as your
example.wxs
, any standalone executable will do (for example
C:\WINDOWS\system32\notepad.exe
if you have nothing else available). Rename the application to
example.exe
. Change the following lines in your XML file
example.wxs
:
="1.0"
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111"
Name="Example Product Name" Version="0.0.1" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
</Feature>
</Product>
</Wix>
Run
make_installer.bat
again to build the package and double click
example.msi
to install it. This time there will be a directory called
Example
in your Program Files folder and the
example.exe
will be installed there. You can uninstall your application via Add/Remove Programs in the Control Panel or right click on MSI file and choose Uninstall.
Create a start menu entry
This adds your example application to the start menu. Since a start menu entry is a shortcut and not a real file, a registry entry is needed. Change the following lines in your XML file
example.wxs
:
="1.0"
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111"
Name="Example Product Name" Version="0.0.1" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Example">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Example Shortcut Name" Description="Example Product Name"
Target="[INSTALLDIR]example.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Example Company Name\Example Product Name"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
</Product>
</Wix>
Run
make_installer.bat
again, test and uninstall your
example.msi
.
How to do software upgrades
A little bit of configuration is needed for software upgrades, because some values are used repeatedly we define them as variables. Change the following lines in your XML file
example.wxs
:
="1.0"
= "0.0.1"
= "12345678-1234-1234-1234-111111111111"
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)"
Name="Example Product Name" Version="$(var.ProductVersion)" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
<UpgradeVersion Minimum="0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no"
Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Example">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Example Shortcut Name" Description="Example Product Name"
Target="[INSTALLDIR]example.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Example Company Name\Example Product Name"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
</Product>
</Wix>
Two things are important for software upgrades: increase the ProductVersion in every new release, the UpgradeCode has to stay the same for all releases! Run
make_installer.bat
again, build two packages with different ProductVersion numbers and name them
example_001.msi
and
example_002.msi
. The installer will check if an old version is installed and replaces it, in case a newer version is already installed it will abort with an error message.
Final touches
Let's add icon and links for support information, they are are shown via Add/Remove Programs in the Control Panel. Copy an icon into the same directory as your
example.wxs
, any graphics file with ending ico will do (for example
http://www.codeproject.com/favicon.ico if you have nothing else available). Rename the file to
example.ico
. Change the following lines in your XML file
example.wxs
:
="1.0"
= "0.0.1"
= "12345678-1234-1234-1234-111111111111"
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)"
Name="Example Product Name" Version="$(var.ProductVersion)" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Icon Id="ProductIcon" SourceFile="example.ico"/>
<Property Id="ARPPRODUCTICON" Value="ProductIcon"/>
<Property Id="ARPHELPLINK" Value="http://www.exampleproduct.com"/>
<Property Id="ARPURLINFOABOUT" Value="http://www.examplecompany.com"/>
<Property Id="ARPNOREPAIR" Value="1"/>
<Property Id="ARPNOMODIFY" Value="1"/>
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
<UpgradeVersion Minimum="0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no"
Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Example">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Example Shortcut Name" Description="Example Product Name"
Target="[INSTALLDIR]example.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Example Company Name\Example Product Name"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
</Product>
</Wix>
Download the final
WiX installer example. Don't forget to replace text starting with "
12345678-1234-1234-1234
" with unique
GUIDs in your final installer. Also check every place with text "example" and replace it with your product/company name.
Okay, that's it. You now know the basics and are ready to make your own MSI installer! :)
Find more information
Once you are familiar with a simple MSI installer, you probably want to add more files and a GUI. Here's where to find further information:
Most features can be added by adding more information to the XML file and changing the make file arguments.
Trouble shooting
- A WiX command line tool crashes with the following error: The application failed to initialize properly (0xc0000135)?
This is a known problem on Windows XP, you need to install the Microsoft .NET Framework, see above in the 'getting started' section.
- A WiX command line tool gives the following error: program is not recognized as an internal or external command?
You need to update the path and manually add the WiX binaries path, see how to set the path in Windows 2000/Windows XP. The default path for an English Windows XP is C:\Program Files\Windows Installer XML v3\bin
...you can find the correct path for your PC in the Windows Explorer, search for the file candle.exe
(the name of the WiX compiler).
- A WiX command line tool gives a CNDL0104 error: Not a valid source file?
Make sure your XML file is valid. Use an XML editor or for a quick check open the file in Firefox, it will show XML parsing errors in red.
- Installing or updating .NET Framework takes forever?
Yes, better get another coffee. There will also be one or more reboots, you will have lots of waiting time.
- The .NET Framework installed a Firefox add-on without asking for permission, how do I get rid of it?
The easiest way is to open the Firefox menu Tools -> Add-ons -> Microsoft .NET Framework Assistant and click on 'Disable'. This won't uninstall it, for further information on how to completely remove it see KB963707.
- My example MSI file won't install and nothing happens, what can I do?
MSI files require administrative privileges, make sure you are installing the MSI examples as administrator.
- Some of the WiX tutorial from the internet don't work, why is that?
There are different versions of WiX, the current version is WiX v3.0 (at time of writing). If tutorials and blogs give contradicting information, it's because they haven't labelled which version of WiX they used. For example v2.0 is obsolete and v3.5 is planned with new features you can't use yet.
- How do I generate GUIDs for my installer?
There are command line tools available or create GUIDs online. You will need at least one for the UpgradeCode and one for each component in the XML file.
Conclusion
Advantages:
- Write a Windows installer with free tools (WiX is open source)
- WiX configuration can be done in any XML or text editor
- Easy integration into automated build scripts
- Multi language install packages are possible (via undocumented MSI hack)
- Active mailing list for support
Disadvantages:
- GUI customisation is difficult, the default templates are usually not sufficient
- Localisation is incomplete in WiX v3.0, e.g. no Swedish, Danish, Norwegian, Finnish (according to WiX Localization Project)
- Documentation is old and incomplete, you have to search trough various blogs
- Underlying MSI installer concept is complex and time consuming to learn, MSI is not a simple package manager
- File system and registry cleanup is not made particular easy, you often have to write custom actions for uninstall/upgrade
- Software versions are limited to 3 parts of the version (major.minor.build) or software upgrades won't work
External links