Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / XML

Working with MSBuild - Part 2

Rate me:
Please Sign up or sign in to vote.
4.87/5 (14 votes)
1 Oct 2012CPOL4 min read 51.9K   34   4
Exploring Various Target Samples

Introduction

In the previous article (can be found here), we covered -

  • What are MSBuild?
  • It’s structure, its nodes
  • A simple example of how to run it.

This article will be about the different tasks that are commonly achieved with MSBuild scripts for automating publishing/deployment of an application.

Why do we need automation?

Automating a build processes has following advantages –

  • Minimised risks
  • Require lesser skills for running efficiently.
  • Easy to run as for a deployment person, it’s much easier to run .bat file that has the MSBuild command in it for publish than actually opening the application with VS and checking all dependencies and configurations.

Common Properties

While individual MSBuild script may have varied scripts, there are quite a few properties that are common and are found in almost all MSBuild scripts. In MSBuild scripts properties are named by developers. So while the actual name may differ amongst scripts but the purpose of those properties are common. Such common properties (names can be standardised at project, team and geography level to increase readability) are as follows: -

  • Configuration – This property checks the configuration of publish i.e. whether it’s to be Release or Debug.
  • TF – A property that maps as to where the TF.exe resides on the system. TF .exe is important when you want to execute TFS based commands
  • MSTestExe – A property that maps as to where the MSTest.exe resides on the system. This is important if you want to run the automatically with MSBuild scripts.
  • TFSProject – A property to be declared to get the location of the solution that you want to publish from TFS.
  • TFSBuildWorkSpaceName – A property to be declared to get the workspace name.
  • WorkingDirectory - A property declared to map the location at which the commands are to be executed
  • SolutionName – The property declared to map the actual solution file.

The list continues ... so let’s walk through couple of targets and get to have a better understanding. This is to be noted that properties are accessible via "$" prefixes to the property name

Tasks / Targets

Scope of the tasks that could be achieved with MSBuild is vast. Given below is a very concise set of activities –

  • IO Activities

Target - GetVersion

Purpose - Get the version specified in text file and display the same.

Definition of Target:

<Target Name="GetVersion"> 

<Message Text="GetVersion: Reading version number from VersionInfo.txt" /> 

<Attrib Files="$(WorkingFolder)\VersionInfo.txt" Normal="true" /> 

<Version VersionFile="$(WorkingFolder)\Build\VersionInfo.txt"> 

<Output TaskParameter="Major" PropertyName="Major" /> 

<Output TaskParameter="Minor" PropertyName="Minor" /> 

<Output TaskParameter="Build" PropertyName="Build" /> 

<Output TaskParameter="Revision" PropertyName="Revision" /> 

</Version> 

<Message Text="GetVersion: $(Major).$(Minor).$(Build).$(Revision)" /> 

</Target>

Properties to be declared:

<PropertyGroup> 

<WorkingFolder>C:\MSBUILD tests</WorkingFolder> 

</PropertyGroup>

Command

  1. Description - Specifying the target to run with default value for the declared property

    msbuild GetVersion.msbuild /t:GetVersion

    This has a pre-condition that the a VersionInfo.txt file should exist at C:\MSBUILD tests\Build

    Output

    Image 1

  2. Description - Specifying the target to run with a specific value different from for the declared property

    msbuild GetVersion.msbuild /t:GetVersion /property:WorkingFolder = "C:\MSBUILD tests\Build\V"

    This has a pre-condition that the a VersionInfo.txt file should exist at C:\MSBUILD tests\Build\V\Build

    Output

    N.B.- This is to be noted that the MSBuild has multiple command options that could explored with help accessible via MSBuild /help command. Please explore the same.

    • Team Foundation Activities

    This is to be noted that in order to execute any TF commands TF.exe should be installed.

Target - UnLock

Purpose – Will unlock all files in the solution specified

Target Definition:

<Target Name="UnLock">

< Message Text="Unlocking...."></ Message >

<Exec Command="$(TF) lock &quot;$(TFSProject) /assemblyinfo.*&quot; /recursive /LOCK:NONE /workspace:$(TFSWorkSpaceName) /server:$(TFSServer) " WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" />

<Message Text="Unlocking Complete...."></ Message >

</ Target >

Property Declaration:

<PropertyGroup>

<WorkingFolder>C:\Projects\MSBUILD</WorkingFolder>

<TFSProject>$/[server location]/[solution folder name]</TFSProject>

<TFSWorkSpaceName>SomeWorkSpace</TFSWorkSpaceName >

<TFSServer>tfs.thisdomain.com</TFSServer>

</PropertyGroup>

Command Declaration

msbuild Unlock.msbuild /t: UnLock

N.B. – This is to be noted that since these are related to TFS, hence the TFS specifc details have been suppressed and actual output is not displayed

Target - GetLatest

Purpose – Will get latest of the solution

Target Definition:

<Target Name="GetLatest"> 

<RemoveDir Directories="$(WorkingFolder)" /> 

<MakeDir Directories="$(WorkingFolder)" /> 

<Exec Command="$(TF) workspace /delete $(TFSWorkSpaceName) /server:$(TFSServer) /noprompt" WorkingDirectory="$(WorkingFolder)" ContinueOnError="true" /> 

<Message Text="Temporary build Workspace deleted" /> 

<Exec Command="$(TF) workspace /new $(TFSWorkSpaceName) /server:$(TFSServer) /noprompt" WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" /> 

<Message Text="New temporary build Workspace created" /> 

<Exec Command="$(TF) workfold /workspace:$(TFSWorkSpaceName) /server:$(TFSServer) /unmap $/" WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" /> 

<Message Text="Default working folder for new temporary build workspace unmapped" /> 

<Exec Command="$(TF) workfold /workspace:$(TFSWorkSpaceName) /server:$(TFSServer) /map $(TFSProject) $(WorkingFolder)" WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" /> 

<Message Text="Working directory mapped to new temporary build workspace" /> 

<Exec Command="$(TF) get &quot;$(TFSProject)&quot; /recursive /version:T /noprompt" WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" /> 

</Target>

Property Declaration:

<PropertyGroup>

<WorkingFolder>C:\Projects\MSBUILD</WorkingFolder>

<TFSProject>$/[server location]/[solution folder name]</TFSProject>

<TFSWorkSpaceName>SomeWorkSpace</TFSWorkSpaceName>

<TFSServer>tfs.thisdomain.com</TFSServer>

</PropertyGroup>

Command Declaration :

msbuild GetLatest.msbuild /t: GetLatest

N.B. – This is to be noted that since these are related to TFS, hence the TFS specifc details have been suppressed and actual output is not displayed

Snapshot of Other Tasks

The list of tasks that could be achieved is both extensive and diverse. Just for up start up,  very concise list of activities that could be furthur achieved is given below:

Checkout:

<Exec Command="$(TF) lock &quot;$(TFSProject) /*.*&quot; /recursive /LOCK:NONE" WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" />

<Exec Command="$(TF) checkout /lock:checkout /recursive &quot;*.*&quot;" WorkingDirectory="$(WorkingFolder)" ContinueOnError="false" />

Check in:

<Exec Command="$(TF) checkin /recursive &quot;*.*&quot;" WorkingDirectory="$(WorkingFolder)" ContinueOnError="true" />

<Exec Command="$(TF) label &quot;SetVersion $(Major).$(Minor).$(Build).$(Revision)&quot; $(TFSProject) /comment:&quot;MSBuild Automated Build Label&quot; /owner:$(username) /recursive" WorkingDirectory="$(WorkingFolder)" ContinueOnError="true" />

Set Version (depending on some other tasks):

<Target Name="SetVersion" DependsOnTargets="GetVersion;CheckOut"> 

<Message Text="SetVersionInfo: Updating Versions in all files" /> 

<CreateItem Include="$(WorkingFolder)\**\*.*"> 

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

</CreateItem> 

<Attrib Files="@(Files)" Normal="true" /> 

<FileUpdate Files="@(Files)" 

Regex="FileVersionAttribute\(&quot;(\d+)\.(\d+)\.(\d+)\.(\d+)&quot;\)" 

ReplacementText="FileVersionAttribute(&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" 

/> 

<FileUpdate Files="@(Files)" 

Regex="FileVersion\(&quot;(\d+)\.(\d+)\.(\d+)\.(\d+)&quot;\)" 

ReplacementText=" FileVersion (&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" 

/> 

<FileUpdate Files="@(Files)" 

Regex="FileVersion\(&quot;(\d+)\.(\d+)\.(\d+)\.(\d+)&quot;\)" 

ReplacementText="FileVersion(&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" 

/> 

</Target>

N.B. -

  • Output Parameters from commands executed are accessed via "@" prefixes to the parameter name
  • DependsOnTargets specifies whether the Target in question depends on the successful run of other targets or not. Multiple target dependencies are specified by comma separation.

Well that’s it as of now. We will continue to with customizing TFS activities with C# in the next part in the series.

The above set of TF activities is only a snap shot of how to achieve tfs related activities through the MSBuild. The list of tasks that could be done through TF commands in MSBuild is exhaustive. The best possible way to understand them is to practice.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 3 Pin
VMAtm21-May-13 2:04
VMAtm21-May-13 2:04 
SuggestionMSBuild Community Tasks Pin
ryba.ml7-Oct-12 22:23
ryba.ml7-Oct-12 22:23 
GeneralMy vote of 4 Pin
Klaus Luedenscheidt1-Oct-12 19:14
Klaus Luedenscheidt1-Oct-12 19:14 
GeneralRe: My vote of 4 Pin
girlprogrammer13-Aug-13 1:51
girlprogrammer13-Aug-13 1:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.