This is the first post about building a WiX 3 installer from zero. The reason I’ve decided to write this WiX series is that the good sources are quite hard to find and examples even harder.
The finished installer (at the end of the series) will be localized in 2 languages, have localized EULA check, product key validation via a custom action, updating (and killing the running app when updating) and wrapping both localized MSI’s into a bootstrapper that will enable you to choose the installation language and install prerequisites like .Net framework 3.5. Those are the general features and we’ll well dive into each feature in a separate post.
We’ll be using WiX 3.0.5419.0 in Visual Studio 2008. You can download WiX at the SourceForge Wix Site. I’m expecting that you’re familiar with basic WiX operations and how to make the WiX project.
To help you with your WiX development be sure to use the ORCA tool (download via Win SDK or directly from here) for viewing/editing MSI tables and default MSI logging capabilities like “msiexec /i SuperForm.Installer.msi /l*v SuperFormLog.txt” which will write a very detailed log of what it’s doing at each step.
The application we’ll be installing is called SuperForm which solves all your label’s text color needs by using the awesome action of pressing a button.
The first thing we have to do is to create a new System Environment variable SuperFormFilesDir containing the path to the directory where you keep the files you’ll install on the users computer. We’ll be using this variable in the automated building of wxs fragment file that holds the correct directory/files structure. This is my preference in environments with multiple developers. It is highly unlikely that all developers have the same directory structure. If you work alone you can also take the “preprocessor variables” route described below in Project Properties –> Build. I’ll be using the System Environment variable approach.
We have three projects of which the most important for us is the WiX project. Logically the project is divided into 7 folders and 1 main file.
- CustomActions: stores WiX fragments that define different custom actions (CA’s). You can have 1 fragment per CA or all CA’s under 1 fragment. I prefer fragment per CA.
- CustomDialogs: stores WiX fragments that define our custom built dialogs. there are 2 we’ll have: The overwritten existing EULA dialog and fully custom product key check dialog.
- Fragments: stores WiX fragments that are either auto generated by Heat.exe directory harvesting or manually built like inserting some values into the registry.
- Includes: stores WiX include files that hold pre processor variables. Wxi files must be included at the top of each wxs file you’re using variables in.
- Lang: stores localization stuff
- de-de: German installer. Stores German EULA, custom localization file and official German WiX translations.
- en-us: US English installer. Stores English EULA and custom localization file.
- Packages: output for the actual MSI’s. This replaces the bin folder.
- de-de: stores the German MSI installer.
- en-us: stores the English MSI installer.
- Resources: stores different resources like icons, jpg’s, etc… used in the installer.
- SuperForm.wxs: master installer files where all the magic happens.
We also need to include some references:
- SuperForm.CustomAction: needed to run our custom actions stored in the SuperForm.CustomAction.dll project
- WixNetFxExtension: needed for conditional check id .Net 3.5 is installed and abort if not.
- WixUIExtension: needed to include and modify any UI elements.
- WixUtilExtension: needed to run CloseApplication built in custom action.
All non WiX files (others than wsx, wxi, wxl) don’t really need to be included in the project but i like to include them for clarity. This way we see exactly what is in the installer from the project itself.
SuperForm.Install WiX project properties:
- Installer: No changes
- Change “Output Path” to “Packages\”. This is needed to respect the project structure. You could use the default ($Configuration)\bin but I prefer not to. The ($Configuration) part is only useful if you’re building both 32 and 64 bit installers.
- If you don’t like adding a new System Environment variable you can do this instead. To “Define preprocessor variables” add the SuperFormFilesDir=pathToTheFolderWhereTheFilesToBeInstalledAre;”. Variables are delimited by semicolons (;).
- Build Events:
- To “Pre-build event” add "$(WIX)bin\heat.exe" dir "$(SuperFormFilesDir)" -cg SuperFormFiles -gg -scom -sreg -sfrag -srd -dr INSTALLLOCATION -var env.SuperFormFilesDir -out "$(ProjectDir)Fragments\FilesFragment.wxs". Heat.exe makes a wxs file with proper directory/file structure from the specified directory. We’ll take a detailed look into this in a future post.
- You can skip this for now but remember to add it later! To “Post-build event” add “$(SolutionDir)BootstrapperBuild.bat $(TargetDir) $(TargetFileName) $(SolutionDir)”. This will be used at the end to build the bootstrapper.
- Paths: No changes
- Tool settings: No changes
Resources for WiX development
- WiX Documentation – official docs, what else.
- Rob Mensching – creator and main contributor of WiX.
- WiX tutorial by Gábor DEÁK JAHN – this is an excellent tutorial that covers all aspects of WiX!
- From MSI to WiX by Alex Shevchuk – a Technet series on how to build an installer with WiX.
- WiX Mindcapers wiki – great wiki with lots of great stuff
- Joy of Setup by Bob Arnson – a setup blog with lots of good info.
- WiX tricks and best practices – StackOverflow wiki with some more links to best practices with WiX.
WiX 3 tutorial by Mladen Prajdić navigation