Search
Close this search box.

Building a MSI/Setup project using MSBuild/Team Build

Update: This can be accomplished with the MsBuild Extension Pack using the MsBuild.ExtensionPack.TFS.DevEnv

Team Build is great for building Projects applications such as Windows or Web apps.  However it is not able to build Install packages.  Because of this you have to use the Visual Studio build command line option, and copy the .msi and setup.exe files out of the local build directory.  My builds usually copy the built files from to a stage or production server, However this is difficult to do, as no TB/MSbuild variables correctly reference the local build location.  To build a visual studio setup project, I did the following:

  1. Enable building in the Solution configuration manager.  Select the configuration manger, checked build next to the Install project name. 
  2. Open the ApplicationSetup.proj file in a text editor. Searching for ProjectOutput, SourcePath, I confirmed the path was relative to the project file (..\\obj\\Release\\HelloWorld.exe) rather then literal (C:\HelloWorld\obj\\Release\\HelloWorld.exe).
  3. Modified the Build project, adding the build target type
<Target Name="AfterCompile">

    <Exec Command=
    "&quot;$(ProgramFiles)\Microsoft Visual Studio 9.0\Common7\IDE\devenv&quot;
    &quot;$(BuildDirectory)\HelloWorld\HelloWorldInstall\HelloWorldSetup.vdproj&quot;
    /Build &quot;Release|Any CPU&quot;"/>
</Target>

4. Created a target to copy the files.  Unfortunately, the built executables are not copied to the drop location.  Their is no TFS build variable that represents the build location.  To copy the files, I had to use a literal path to the build location.  The files were referenced as “C:\build\HWBuildLoc\…” instead of $(SolutionRoot). The MSDN documentation suggests using $(SolutionRoot) to get the local build location, however this returns the incorrect directory. 

<Target Name="AfterDropBuild">

    <Time Format="yyyyMMdd_HHmmss">

        <Output TaskParameter="FormattedTime" PropertyName="BuildDate" />

    </Time>

 

    <!-- Copy files to Stage -->

    <CreateItem Include="\\StageServer\HelloWorld_$(BuildDate)">

        <Output PropertyName="BuiltProjectStagePath"
        TaskParameter="Include" />

    </CreateItem>

 


   
 

    <CreateItem Include=
        "C:\build\HWBuildLoc\HelloWorld\HelloWorldInstall\Release\**\*.*" >

        <Output ItemName="FilesToCopy" TaskParameter="Include" />

    </CreateItem>


    <!-- Copy installer -->

    <Copy SourceFiles="@(FilesToCopy)"

         DestinationFiles=
         "@(FilesToCopy ->'\\StageServer\StageDirecoty\%(RecursiveDir)%(Filename)%(Extension)')"

         ContinueOnError="true"/>

</Target>

5. This does cause the application to be built twice: once through the normal build process, and again by the visual studio command line call. 

I referenced the following:

  1. Team Build target map
  2. Team Build Property Reference by Aaron Hallberg
  3. Walkthrough: Configuring Team Build to Build a Visual Studio Setup Project
This article is part of the GWB Archives. Original Author: David Williams

Related Posts