At some point with any decently complex project, you are going to need
to start customizing your build process. Visual Studio makes this
possible, and not too terribly painful, by giving developers the ability
to write custom MSBuild project files. But eventually, you are going to
hit the limit of what the MSBuild XML syntax can do for you - but when
you reach that point, there is something else waiting - custom tasks!
MSBuild gives you the ability to write custom build tasks in C# (or any
.NET language), and use those tasks inside of MSBuild project files. We
are going to be taking a look today at how to create these tasks and how
to use them.
So first, we need to create a task. To do this, you need a new Visual
Studio project - any type will do, but it is easiest to go with a class
library:
Once you have a new blank project, we need to add a few references in
order to get the classes we need to create a task. To do this, right
click on "References" in Solution Explorer and choose "Add Reference":
Clicking that will bring up the Add Reference dialog. Once in here, you
need to choose two things
Microsoft.Build.Framework
and
Microsoft.Build.Utilities.v3.5
:
Now it is time to actually start creating the task. Every task derives
from
Microsoft.Build.Utilities.Task,
which is a abstract class with a single method that you are required to
implement:
using System;
using Microsoft.Build.Utilities;
namespace BuildTask
{
public class MyTask : Task
{
public override bool Execute()
{ throw new NotImplementedException(); }
}
}
This execute method is what will get called when your task is executed
by MSBuild. For today we are going to create an extremely simple execute
method, but really the sky is the limit. You are in C# code now - so
you have everything that C# and the framework offers you right at your
fingertips.
using System;
using Microsoft.Build.Utilities;
using System.IO;
namespace BuildTask
{
public class MyTask : Task
{
public string FileName { get; set; }
public override bool Execute()
{
try
{ File.WriteAllText(FileName, DateTime.Now.ToString()); }
catch
{ return false; }
return true;
}
}
}
All our task here does is write the current date/time to the file given
by
FileName
. If it succeeds, it returns true, otherwise, it returns
false. Every property that you expose on your task class is one that you
can set when using the task (although since you have to set it in XML,
it is generally best to go with strings). The return value of the
Execute
method is used by MSBuild to determine if your task
successfully completed or not - true means success, false means failure.
And that is really it for writing a task. Now on to actually using it.
To do this, we first have to write our own custom MSBuild project file.
If you are already customizing your build process, you probably have one
already. Here we are going to have one that is about as simple as it can
get:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="All"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile="BuildTask.dll" TaskName="MyTask"/>
<Target Name="RunMyTask">
<MyTask FileName="MyDate.txt" />
</Target>
</Project>
The
UsingTask
tag lets MSBuild know that you will be using a task
named MyTask
from the dll "BuildTask.dll". Once you have that set up,
you can use the task inside of any target in your project file - here we
are running it in the "RunMyTask" target, and giving it a file name of
"MyDate.txt".
To actually run this target through MSBuild, you will need to do the
following on the command line (I created a batch file):
call "%VS90COMNTOOLS%\vsvars32.bat"
msbuild /target:RunMyTask TaskTest.proj
And when you do this, you will get some output that looks like the
following:
C:\BuildTask\bin\Debug>TaskTest.bat
C:\BuildTask\bin\Debug>call "c:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
C:\BuildTask\bin\Debug>msbuild /target:RunMyTask TaskTest.proj
Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3074]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 5/27/2009 7:42:12 PM.
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.01
C:\BuildTask\BuildTask\bin\Debug>
And guess what? There is a file sitting in that directory called
"MyDate.txt" that holds the current date/time.
Well, that about covers the basics of writing and using custom build
tasks. This really only scratches the surface of what you can do, both
with custom tasks and MSBuild in general, but I think I'll save that for
a different tutorial. If you have any questions, please leave them in
the comments.
Comments
Post a Comment