ISWIX, LLC View Christopher Painter's profile on LinkedIn profile for Christopher Painter at Stack Overflow, Q&A for professional and enthusiast programmers

Friday, September 7, 2007

Build InstallShield using TFS

contributed a `keep it simple` sample to Windows Installer MVP Stefan Krueger's InstallSite that demonstrates building a C# windows application and then package it using InstallShield 2008 via TFS Team Build. The example can be downloaded here:

The following is a step by step on how to wire it up:

Prepare To Build:
1) Extract and add the TeamBuildTypes and WindowsProduct folders to your TFS Project source control.

2) Update WorkspaceMapping.xml ServerItem attribute to reflect where you added the WindowsProduct folder in your source control tool.

3) Update TFSBuild.proj:

Set the BuildMachine ProjectExtension to reflect the name of your build machine. The build machine only needs to have .NET 2.0, TeamBuild and InstallShield 2008 or InstallShield 2008 Stand Alone Build Engine installed. Visual Studio 2005 is not required.

Update the TeamProject Property to reflect which TFS Project you added the files to. ($/PROJECT )

Update the DropLocation Property to reflect where you want the builds dropped/archived.

Commit your changes and run a build. When it's all done you should see a good build with an Install folder containing Setup1.msi and a Release folder containing WindowsApplication1.exe.

How It Works in the context of InstallShield:

This sample uses standard TFS TeamBuild solution based build concepts. I don't like to use Project Output references so instead I use an xcopy post build command in the C# project to drop the $(TargetPath) into a folder underneath the InstallShield project directory. I also use Project Dependencies to make sure the C# code compiles first.

InstallShield 2008 has built-in MSBuild/VSIP support. In addition to the standard XML .ISM project, there is an MSBuild file called Setup1.isproj. This document teaches MSBuild/TeamBuild/Visual Studio how to interact with and build the .ISM project. Basically it matches your solution configuration manager settings to the InstallShield Product Configuration/Release settings.

Finally I've instructed InstallShield to do a postbuild event and copy the MSI to ISProjectFolder\..\..Binaries\Install. This allows TFS to include the MSI as part of it's BinariesRoot Drop pattern.

What's Not Included:

This is a simple example and doesn't implement advanced patterns like versioning the ISM/MSI. In my day job I import a build_install.config project that overrides the BeforeCompile target and inserts a call to a custom build task called VersionInstallShield. This task uses COM Interop Reflection to invoke the InstallShield SAB automation interface and update the ProductVersion property of the ISM before building.


  1. sandi.madden@sbcglobal.netOctober 3, 2007 at 2:05 PM

    I have a question, how can you make TSF to build multiple configurations of the InstallShield project, but not of the Windows application? E.g. you need to build the CDROM install and a downloadable install configuration of the Setup, but only the one Release config of the Windows app? Is that possible?


  2. Sure, just define multiple ConfigurationToBuild elements. There may be situations where you want to build the windows application twice ( debug and release ) and situations where you don't ( release cdrom and release webdownload ).

    It's all about how you organize and configure your solution.

    As an aside, I work on large asset based products in a product line development environment. My .NET is split out across many solutions and my installs are in their own solutions. This allows me to branch/merge and build atomically while composing products from differnt groups of asset packages.

  3. Hi Chris, how could you generate the folder TFSPROJECT\WindowsProduct\Setup1\ProgramFilesFolder after build?

    I created similar project but I got no such folder after successful build?