Hi there! In this post I am going to explain how to use WiX tools set in Visual Studio to create windows installer package or MSI.
- What is WiX and how and where to get Wix.
- Creating WiX installer in Visual Studio.
- Little introduction about the various components in Wix.
This post gives you basic understanding on how to use WiX inside visual studio and a sample application with how to install and uninstall from user’s computer.
What is Wix (Windows Installer XML)?
Wix is a framework for building an installer for windows-based software also called Windows Installer.
All the WiX source files fed into the WiX compiler (Candle.exe) , generates half-digested files called Wixobj, in the send and final phase Light.exe uses the first phase wixobj file and generates final package, .msi file.
Wix way:
Windows installer has many features, in this post, we are going to learn basic building block of Windows Installer and the core components / Xml Elements to create Sample installer using visual studio.
Visual Studio:
Visual studio has support for WiX Projects. WiX toolset installer automatically installs the Visual Studio support templates. You can create WiX setup solution or WiX project, by writing WiX XML source files to describe your installation requirements that gets translated into Windows Installer .msi file, see below diagram.
Creating a windows installer or MSI , has always been a challenging task because you have other option InstallShield to do the job but you will forever dependent on them. Best of all WIX is free and open source product, it has wider user base and dedicated community developers.
When I started learning , I got a question in my mind, “ Is Wix solves my problem” , YES, after spending time and seeing the benefits of creating an installer package , some of the features that you get when you build a Windows Installer package with WIX.
- All of your executable files can be packaged into one convenient bundle, simplifying deployment.
- Your software is automatically registered with Programs and Featurers.
- Windows takes care of uninstalling all of the components.
- You can repair files if some one accidently removed , create different versions of your installer and if some thing goes wrong while installing you software, the end user’s coputer can be rolled back.
- You can create Wizard-style dialog to guide the user through the installation.
Finally, my favorite reason is that it gives you greater control over how things work.
Let’s dive into, where I can get it and how to install the software. You can find the latest version of Wix
http://wixtoolset.org/ . download the stable version, the current version is 3.9 but I am using wix 3.8 stable version here.
Once downloaded, run the wix38 executable , it opens below window , click on “Install”
This installs all of the necessary files need to build Wix projects. Along with this installation, you’ll also get Wix SDK documentation and settings for VS intellisense and project templates.
Wix comes with the tools:
Tool | What is does |
Candle.exe | Compiles WiX source files (.wxs) into intermediate object files (.wixobj) |
Light.exe | Links and binds .wixobj files to create a final .msi file. Also creates cabinet files and embeds streams in an MSI database. |
Lit.exe | Creates WiX libraries (.wixlib) that can be linked together by Light. |
Dark.exe | Decompiles an MSI file into Wix code. |
Heat.exe | Creates a WiX source file that specifies components from various inputs. |
Insignia.exe | Inscribes an MSI with the digital signatures that its external CAB files are signed with. |
Melt.exe | Converts a merge module (.msm) into a component group in a WiX source file. |
Torch.exe | Generates a transform file used to apply changes to an in-progress installation or to create a patch file. |
Smoke.exe | Runs validation checks on an MSI or MSM file |
Luc.exe and Nit.exe | Authors and runs unit tests on custom actions. |
Before using some of the functionality inWix, you can download the recent version of windows installer or you can check your current version by viewing the help file msiexe.exe
Go to windows command prompt -> type msiexe.exe /? Bring up a window.
Here is the link to get the new Window installer, Microsoft download center
http://www.microsoft.com/en-us/download/default.aspx
Before creating Wix Setup project in VS, we need to know about GUID, we use GUID in various places in Wix, when you install your product or software on the end user’s computer, reference to it can be stored in Windows Registry without the change of having name conflicts. By using GUIDs in Windows Installer can be sure that every software application has a unique identity on the system.
Once downloaded and installed Wix tools set , open visual studio and select
New Project | Windows Installer XML (WIX) | Setup Project
This will create a project with a signle .wxs (Wix source) file to add XML markup, the name of the file is Product.wxs
[Note: you can change the name to anything, but extension should be .wxs]
There are seven new project templates:
Setup Project: Creates a Windows Installer package from one or more Wix source files.
Merge Module Project: Creates a merge module (MSM ) file.
Setup Library Project: Create a .wixlib library
Bootstraper Project: Creates a prerequisite bootstraper.
C# Custom Action Project: Create a .NET custom action in C#.
C++ Custom Action Project: Creates an unmanaged C++ custom action.
VB Custom Action Project: Create a VB.NET custom action.
WIX Components:
As you can see, Wix installers must have the following XML elements.
- An Xml declaration
- Wix element root element in your XML document
- A Product element is the child to the Wix element.
- A Package Element
- A Media or MediaTemplate Element
- At least one Directory element with at least one child Component element
- A Feature element.
If you like to learn more about each element in details, click here.
Let’s try to understand little more about each Wix generated elements and their attributes, once you understand each element, and then we will dive into building wix setup project for Web Form or MVC
As you can see from the above Wix main element has xmlns or XML namespace, this brings the core Wix elements into the local code, so we need to add 2 more xmlns to provide IIS, UTIL elements to current code, change the Wix element as below.
<Wix xmlns=”http://schemas.microsoft.com/wix/2006/wi”
xmlns:iis=”http://schemas.microsoft.com/wix/IIsExtension”
xmlns:util=”http://schemas.microsoft.com/wix/UtilExtension>
[Note: if you don’t want IIS – Website , AppPool functionality, IISExtension not required]
If you want to learn more about IISExtension and UtilsExtension schema click on those links.
Product Element:
This is where you define the characteristics of the software you’re installing. Product element’s Id attribute, also called Product Code of your software. It’s always a unique number – a GUID, that Windows will use to uniquely identity your software, you can hardcode the GUID or * will always creates a new GUID for each time you compile the project, recommended to use hard code GUID.
Language code attribute is used to display error message other information in the specified language to the user. It’s a decimal ID; here is the link to Mocrosoft’s LCID.
https://msdn.microsoft.com/en-us/goglobal/bb964664.aspx
The Version attribute is used to set the version number of your software.
The Manufacturer attribute tells the user name of your company or project.
The Upgrade attribute contains GUID , to identify your product across releases.
<Package> element
Here Compressed is really required, if you set Compressed = Yes, compressed files in the source.
[This attribute cannot be set for merge modules]
InstallerScope: Use this attribute to specify the installation scope of this package: per-machine or per-user. When you set InstllerScope=” per-machine “ declares that the package is a per-machine and required elevated privileges to install, Installer behind the scene sets ALLUSERS property to 1.
InstallScope=per-user does not require any privileges to install the package.
InstallVersion: Here version “200” represents Windows Installer 2.0, minimum version required to install this package, if the user’s computer already have older version with the same version, Windows Installer shows upgrade wizard.
<MediaTemplate> Element:
MediaTemplate element comes after package element, what it does is, it compresses the files you are intended to install into CAB files and shipped along with installer as .Cab file extension.
Here only one attribute is important is “EmbedCab”, if set yes, CAB files will be embedded inside the MSI.
EmbedCab= “no”
EmbedCab =”yes”
Before discussing how to set install directory path and how to choose several default directory properties provided by the windows installer , first we need to understand what is the Directory element, how to tell wix installer what files you are going to install under the directory.
A Directory element describes the physical directory path layout for your software or product, also specifies the mappings between source [Published files or to be packaged in to Msi] and target [Target path windows installer to copy those files] directories.
For example, you want to install the software under this path
“C:\ intranet\ SetupProjectSample” .
First you have to construct or nest inside the default one provided by wix.
Default directory is “<Directory Id=”TARGETDIR” Name=”SourceDir”>”
Important thing to note here is, before constructing any Directory elements hierarchy with a Directory element with an Id attribute “TARGETDIR” and a name value of SourceDir.
Installer sets TARGETDIR to the local hard drive with the most free space, most cases “C: drive”.
[You can set the TARGETDIR to another drive letter during installation time.]
<Directory Id=”TARGETDIR” Name=”SourceDir”>
<Directory Id=”intranetFolder” name=”intranet”>
<Directory Id=”INSTALLLOCATION” Name=” SetupProjectSample ” />
</Directory>
</Directory>
When creating your own directory, you must provide the Name attribute.
Wix internal Directory table structure.
No | Column | Id | Name/ Value |
1 | DefaultDir | TARGETDIR | SourceDir |
2 | Directory | IntranetFolder | C:\intranet |
3 | Directory | INSTALLFOLDER | C:\intranet\ SetupProjectSample |
Now we learned how to map the target directory that you want create during the installation, next step is to copy files into them.
Before adding file, one important point is, Windows installer expects every file to be wrapped up in a component element before it’s installed.
Adding text file:
Right click on setup project and select -> new item -> from the popup select “Text File” form WiX template and name it to “InstallMe.txt” click on add button.
Here we need to understand little bit about the Component element , every file should be wrapped inside a component and each Component element have a unique GUID , which allows windows to track each file and gets installed on the end user’s computer. During the installation, this information stored in the windows registry, this allows windows to find each and every file of your software during an uninstall, so that your software completely removed from the user’s computer.
Create a Component element:
<Component Id=”InstallMeTXT”
Guid=”EDBF1BC5-76F4-43B6-ACA0-64906D389759″>
<File Id=”MyIntranetDir_InstallMeTXT”
Source=”InstallMe.txt”
KeyPath=”yes” />
</Component>
I have created a new component called InstallMeTxt and File element inside the component references the file that’s going to be installed, it’s the InstallMe.txt file located in the current directory( same directory as your WiX source file)
You can specify absolute or relative path using Source attribute.
KeyPath =”yes” marks the file element as the keypath file and you should only include one File inside a component, the advantage is , when you trigger repair keypath file will be replaced if it’s missing.
Now we have to add component to a directory, you have several options to do.
- Add your component elements directly inside the target Directory element.
- Use DirectoryRef element to reference your directories.
- Group your components inside of a ComponentGroup and use its Directory attribute to set the target directory.
Option 1:
Add component as child to INSTALLFOLDER directory.
<Directory Id=”TARGETDIR” Name=”SourceDir”>
<Directory Id=”intranetFolder” Name=”intranet”>
<Directory Id=”INSTALLLOCATION” Name=”SetupProjectSample” />
<Component Id=”InstallMeTXT”
Guid=”E8A58B7B-F031-4548-9BDD-7A6796C8460D”>
<File Id=”MyIntranetDir_InstallMeTXT”
Source=”InstallMe.txt”
KeyPath=”yes” />
</Component>
</Directory>
</Directory>
Above code snippet instructs the installer to copy the InstallMe.txt file to c:\intranet folder that we’re creating on the end user’s computer.
This is the simplest and easiest solution, not recommended for more than 10 files.
Option 2:
Use DirectoryRef element to reference your directories, one benefit of this option is, you can keep the Xml markup elements that define your directories independent from the markup that add files to those directories.
Place below code after <directory id=”TARGETDIR> element inside <Fragment> element
<Fragment>
<Directory Id=”TARGETDIR” Name=”SourceDir”>
<Directory Id=”intranetFolder” Name=”intranet”>
<Directory Id=”INSTALLLOCATION” Name=”SetupProjectSample” />
</Directory>
</Directory>
<DirectoryRef Id=”INSTALLLOCATION” >
<Component Id=”InstallMeTXT”
Guid=”E8A58B7B-F031-4548-9BDD-7A6796C8460D”>
<File Id=”MyIntranetDir_InstallMeTXT”
Source=”InstallMe.txt”
KeyPath=”yes” />
</Component>
</DirectoryRef>
</Fragment>
After adding the DirectoryRef element inside the Fragment element, you need to add this DirectoryRef element inside the Feature element. Feature element is the direct child of Product element. If failed to do so, WiX shows this message
[Error 102 Found orphaned Component ‘InstallMeTXT’. If this is a Product, every Component must have at least one parent Feature. To include a Component in a Module, you must include it directly as a Component element of the Module element or indirectly via ComponentRef, ComponentGroup, or ComponentGroupRef elements. ]
Now go to Feature element add child ComponentRef element, here is the code.
<Feature Id=”ProductFeature” Title=”SetupProjectSample” Level=”1″>
<ComponentRef Id=”InstallMeTXT”/>
</Feature>
Here the id=”InstallMeTXT” points to Component element inside DirectoryRef element.
Option 3:
Group your components inside of a ComponentGroup and use its Directory attribute to set the target directory.
<Fragment>
<Directory Id=”TARGETDIR” Name=”SourceDir”>
<Directory Id=”intranetFolder” Name=”intranet”>
<Directory Id=”INSTALLLOCATION” Name=”SetupProjectSample” />
</Directory>
</Directory>
<ComponentGroup Id=”SetupProjComponents” Directory=”INSTALLLOCATION”>
<Component Id=”InstallMeTXT”
Guid=”E8A58B7B-F031-4548-9BDD-7A6796C8460D”>
<File Id=”MyIntranetDir_InstallMeTXT”
Source=”InstallMe.txt”
KeyPath=”yes” />
</Component>
</ComponentGroup>
</Fragment>
Reference the ComponentGroup in Feature element of Product element.
<Feature Id=”ProductFeature” Title=”SetupProjectSample” Level=”1″>
<ComponentGroupRef Id=”SetupProjComponents”/>
</Feature>
Once you done adding files to components and referenced in side product features, build the solutions, on successful, you can see MSI under the bin folder [Debug or Release].
Here are the steps to run the MSI.
Go to Start menu à command Prompt à right click à choose Run as Administrator.
Change the directory to point to your debug– > bin folder. You can copy to any directory and point to that directory.
Change the directory to point to your bin folder
Use below command to install the software.
msiexec /i SetupProjectSample.msi.
you can see the pic as below
On successful installation, go to C:\intranet folder, InstallMe.txt file copied into user’s computer.
Uninstall the MSI
Go to Start menu à command Prompt à right click à choose Run as Administrator.
Change the directory to point to your bin folder
Now type below command to instruct the windows installer to uninstall the software. See below screenshot.
msiexec /uninstall SetupProjectSample.msi.
Once you click on “Yes” windows installer removes the “Intranet” folder and removed all the installed files from the user’s computer.
Turning Logging on during Installation:
To turn on logging you need to enable logging using command prompt, default windows installer logging is disabled as per my knowledge.
Note: you need to run the command prompt as admin “Run as Administrator”
1. Copy this command into the cmd prompt and press enter to run it. (Debug mode)
reg add “HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer” /v Debug /t REG_DWORD /d 7 /f
2. Copy this command into cmd prompt and press enter to run it.
reg add “HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer” /v Logging /t REG_SZ /d voicewarmupx! /f
3. Re-run the setup and let it fail one more time.
To see logging in Release mode: (Production)
Copy this command into the cmd prompt and press enter to run it:
reg add “HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer” /v Release /t REG_DWORD /d 7 /f
Now logging is enables, you can see the logging after installation or failed installation as below
Re-run the installation.
This command opens the local temp folder, this will be used by windows installer to write the MSI log as text document.
If you open that file, you will see everything related to Product.wxs file , how wix constructed the directory path etc. , eventually if you come to the last line , you will find a statement saying
While installing windows installer, for any reason , Installer resumes the setup closed, you can always look at the logging file (check datatime stamp) to see the status and error if any.
How to look inside your MSI with Orca tool:
When building installers it can often be useful to look inside your installer to see the actual tables and values that were created by the WiX build process.
Microsoft provided a tool with the windows SDK , called Orca, that can be used for this purpose, To install Orca, download from below url and install the tool, you can google “Orca tool” and download accordingly, this is the Url I found when I googled.
Orca.exe is a database table editor for creating and editing Windows Installer packages and merge modules. The tool provides a graphical interface for validation, highlighting the particular entries where validation errors or warnings occur.
http://www.softpedia.com/get/Authoring-tools/Setup-creators/Orca.shtml
Once installed successfully, open the Orca tool, once opened, click on Open Folder menu button and select the MSI file, click open, you will see the tables and values as below.
Conclusion: This post introduces you to how to use WiX tools set in visual studio and we discussed downloading the WiX toolset and its various features by creating a simple MSI package, it is relatively easy, we touched only handful of XML elements need to get started. In the next Post, I am going to explore more complex setups there you will be introduced to elements that are more specialized.
If you have any questions or mistakes in my post, I will be happier to fix and try to educate myself, your feedback is important for me. Here is my email id: sraju1521@gmail.com, have a wonderful day.
Download the code here
Source Code