Creating installer packages has become more complicated recently as the Microsoft decided to not to support installation projects (.vdproj) in VS 2012 upwards. On the top of that there is additional difficulty if we want to auto-create installers on the server that hasn’t got commercial Visual Studio installed – we just cannot do it 🙁
The perfect solution for that is to use WIX installer (Open source). WIX enables you to build installation packages from xml files without relying on Visual Studio. The only component required is to install WIX toolset on the build server (wixtoolset.org)
The main WIX file is the .wixproj file that builds the required package either from inside Visual Studio or from command line – without VS. In that project file we can find some commands that use WIX heat, candle and light modules to create required msi files. See sample below:
Harvesting module will create dynamic list of all files that need to be included into installer. This list is gathered after our website app is published to the local folder:
<Exec Command=""$(WixPath)heat.exe" dir $(PublishF) -dr INSTALLLOCATION -ke -srd -cg MyWebWebComponents -var var.publishDir -gg -out WebSiteContent.wxs" ContinueOnError="false" WorkingDirectory="." />
After harvesting, we can finally build installer. Please note that we can pass in custom parameters when triggering candle module, the parameters must be preceded with the letter “d” e.g. -dMyParam. In our sample we will use this to pass in command line arguments that will define our installer’s name, version, website root etc.
<Exec Command=""$(WixPath)candle.exe" -ext WixIISExtension -ext WixUtilExtension -ext WiXNetFxExtension -dProductName=$(ProductName) -dWebFolderName=$(WebFolderName) -dProductVersion=$(ProductVersion) -dUpgradeCode=$(UpgradeCode) -dProductCode=$(ProductCode) -dpublishDir=$(PublishF) -dMyWebResourceDir=. @(WixCode, ' ')" ContinueOnError="false" WorkingDirectory="." /> <Exec Command=""$(WixPath)light.exe" -ext WixUIExtension -ext WixIISExtension -ext WixUtilExtension -ext WiXNetFxExtension -out $(MsiOut) @(WixObject, ' ')" ContinueOnError="false" WorkingDirectory="." />
For the purpose of this article we will create very simple installer without configuring IIS settings, deploying sql scripts etc. All installer’s basic configuration can be found in UIDialogs.wxs, MyWebUI.wxs, IisConfiguration.wxs – you may want to adjust it for your needs. The file Product.wxs is the main entry point where you can define installation folders, actions, validations etc.
Please note that adding UpgradeCode and MajorUpgrade configuration elements will result in any older installed version to be automatically un-installed prior the installation. Also, any custom params you want to use inside your installer configuration must be used like this $(var.MyParamName).
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="MyCompany" UpgradeCode="$(var.UpgradeCode)" > <MajorUpgrade DowngradeErrorMessage="A newer version of Product Name Removed is already installed."/> .....
After defining our WIX configuration files, we can finally build our installer. We can do it by using batch or Power Shell script, or use Visual Studio to do it. It is because the .wixproj file it’s just normal ms-build file.
When using CI server we can simply run power-shell installation process by passing in our version number (build number, revision etc.) and other parameters we need.
I have attached working sample below. Please don’t forget to install WIX toolset before running it. Also please check if all paths to WIX and msbuild folders are the same on your server (or use environment variables instead).