WiX installer for MVC4 project

This example shows how a MVC4 solution can be setup together with a WiX installation project.

To create a msi installer for a MVC4 project, the solution needs to be built, then the web project must be published, the WiX project harvests the published output and creates an msi installer.

The solution is configured so that in debug, the WiX project isn’t built (Only in release.) This is because a clean build in visual studio will not work unless the web project is published. This is different to VS2010. Here the web deployment project was used.

The Configuration Manager is configured as shown in the 2 images.
ConfiguartionManagerDebug

ConfiguartionManagerRelease

It is important that the WiX harvest is configured to use the default output and not the defined file from the publish profile. (It will then work on all build servers and not just locally.)

SimpleWebAppRef=..\MVCwebproject\obj\$(Configuration)\Package\PackageTmp

In the MVC4 project a publish profile needs to be created. This is required on your build server and needs to be added to your source code (including .user publisher file.)

Example: damienbod.pubxml

<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <SiteUrlToLaunchAfterPublish />
    <publishUrl>$(MSBuildProjectDirectory)\..\deploy</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>

Example: damienbod.pubxml.user

<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
  </PropertyGroup>
  </ItemGroup>
</Project>

And the build command using msbuild: (used by your build server)

msbuild WiXWebInstaller.sln /p:Configuration=Release;RevisionNumber=0.1.0.1;DeployOnBuild=true;PublishProfile=damienbod

I also left RevisionNumber parameter in the msbuild. This is not wired up in this example, but in a productive system, this should be defined in the WiX project and your build server.

With this, a msi can be created for the deployment of MVC4 projects using VS2012. This installer can then be used in an automatic deployment for testing and release management.

Code: https://github.com/damienbod/WiXMVCWebInstaller.git

Why a WiX msi and not web deploy?
The web deployment is only for web projects and cannot be extended, for example adding an extra window service or a self hosted rest service. The installation procedure is also less complicated with a msi. Automatic deployment in your software process will always work with a msi installer, this is not the case with web deployed.

Full Wix Project File

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.7</ProductVersion>
    <ProjectGuid>533458ac-29e6-4f8d-9386-341833257cce</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>WiXWebInstaller</OutputName>
    <OutputType>Package</OutputType>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>Debug;SimpleWebAppRef=..\MVCwebproject\obj\$(Configuration)\Package\PackageTmp</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>SimpleWebAppRef=..\MVCwebproject\obj\$(Configuration)\Package\PackageTmp</DefineConstants>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Product.wxs" />
  </ItemGroup>
  <ItemGroup>
    <HarvestDirectory Include="..\MVCwebproject\obj\$(Configuration)\Package\PackageTmp">
      <AutogenerateGuids>true</AutogenerateGuids>
      <ComponentGroupName>SimpleWebAppGroup</ComponentGroupName>
      <DirectoryRefId>INSTALLDIR_SimpleWebApp</DirectoryRefId>
      <SuppressCom>true</SuppressCom>
      <SuppressRegistry>true</SuppressRegistry>
      <SuppressRootDirectory>true</SuppressRootDirectory>
      <PreprocessorVariable>var.SimpleWebAppRef</PreprocessorVariable>
      <Visible>false</Visible>
      <!--<Transforms>IgnoreFilesInHarvesting.xslt</Transforms>-->
    </HarvestDirectory>
  </ItemGroup>
  <ItemGroup>
    <WixExtension Include="WixVSExtension">
      <HintPath>$(WixExtDir)\WixVSExtension.dll</HintPath>
      <Name>WixVSExtension</Name>
    </WixExtension>
    <WixExtension Include="WixUtilExtension">
      <HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
      <Name>WixUtilExtension</Name>
    </WixExtension>
    <WixExtension Include="WixNetFxExtension">
      <HintPath>$(WixExtDir)\WixNetFxExtension.dll</HintPath>
      <Name>WixNetFxExtension</Name>
    </WixExtension>
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" />
  <!--
	To modify your build process, add your task inside one of the targets below and uncomment it.
	Other similar extension points exist, see Wix.targets.
	<Target Name="BeforeBuild">
	</Target>
	<Target Name="AfterBuild">
	</Target>
	-->
</Project>

Full Wix wxs File

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"  xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <Product Id="*" Name="damienbod power shell example" Language="1033" Version="1.0.1.3" Manufacturer="damienbod" UpgradeCode="cffd6bf0-0b96-421f-9995-04d8772414cd">
    <Package Id="*" InstallerVersion="305" InstallScope="perMachine" Compressed="yes" />

    <MediaTemplate />

    <Property Id="INSTALLPATH">C:\damienbod</Property>

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id='ProgramFilesFolder' Name='PFiles'>
        <Directory Id='damienbod' Name='damienbod'>
          <Directory Id='INSTALLPATH' Name='SimpleWebApp' >
          </Directory>
        </Directory>
      </Directory>
    </Directory>

    <DirectoryRef Id='INSTALLPATH'>
      <Directory Id='INSTALLDIR_SimpleWebApp' Name='SimpleWebApp' />
    </DirectoryRef>

    <Feature Id="ProductFeature" Title="PowerShellInstaller" Level="1">
      <ComponentGroupRef Id="SimpleWebAppGroup" />
      <ComponentRef Id="SimpleWebAppRef" />
    </Feature>

    <Component Id='SimpleWebAppRef' Guid='1bb847ef-912a-49b0-9e32-7788e2b5a6c9' Feature='ProductFeature' Directory='INSTALLDIR_SimpleWebApp'>
      <CreateFolder />
    </Component>

    <MajorUpgrade Schedule="afterInstallInitialize" AllowDowngrades="no" DowngradeErrorMessage="ok" AllowSameVersionUpgrades="yes" />

  </Product>
</Wix>

Links:

http://wixtoolset.org/

http://wix.sourceforge.net/manual-wix3/main.htm

http://www.iis.net/downloads/microsoft/web-deploy

http://www.codeproject.com/Articles/115036/Creating-WIX-Installer-for-ASP-NET-Web-Application

http://blog.iswix.com/2013/09/wix-iswix-support-for-vs-2013-rc.html

4 comments

  1. Dave Shine · · Reply

    This all works great from the command line, but the WiX project fails to build in VS with error “Unresolved reference to symbol ‘WixComponentGroup:SimpleWebAppGroup’ in section ‘Product:*’.” How do I get the solution to build clean in VS?

  2. @Dave Shine: I had the same problem. You can solve this by publishing the web project (this generates files that do not belong to the source code). Right click the selected project. You will see the publish option in the menu. The publish profile is already present and filled in. Just click Next > Next > Publish. After that the build of the wix-project will succeed.
    After that my problem begins: how and when is the actual website created? It seems that the concrete create is not included in this installer? Nevertheless, thanks Damien for the nice article.

    1. … do not forget to build the installer project for Release | x86 configuration.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: