Tuesday, May 8, 2007

Adding Custom Build Steps to a Visual Studio Project

Developing a solution to deploy a timer job involves modifying the CSPROJ file (an MSbuild file) to call the MakeCab utility - this creates a WSP file.

I found that adding an Import statement referring to the custom Targets file (in this case named BuildSharePointPackage.targets) from within the CSPROJ file didn't always produce the right output.

The cause was that MSBuild executes the last build target in order of appearance of Import statements. The csproj file included:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<
Import Project="BuildSharePointPackage.targets" />

The BuildSharePointPackage.targets file did not call any of the standard compile statements in the Microsoft.CSharp.targets file used to build C# projects, so the dlls were not getting rebuilt, and old versions os the dlls were being placed in the WSP file.

The solution was as follows:
  1. Set the DefaultTargets attribute in the Project element of the csproj file to equal the Name attribute of the Target element in the custom targets file:
    <Project DefaultTargets="BuildMossPlus" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  2. Add a DependsOnTarget attribute to the Target element in "BuildSharePointPackage.targets":

    <?xml version="1.0" encoding="utf-8" ?>
    <Project DefaultTargets="BuildMossPlus" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      
    <PropertyGroup>
        
    <MakeCabPath>"C:\Program Files\Microsoft Cabinet SDK\BIN\MAKECAB.EXE"</MakeCabPath>
      </PropertyGroup>
      
    <Target Name="BuildMossPlus" DependsOnTargets="$(BuildDependsOn)">
        
    <Exec Command="(SOME COMMAND)"/>
      </
    Target>
    </Project>


(with help from the MSBuild Team Blog)

No comments: