Notes

Create a Custom MSBuild Task

MSBuild Build Tools C# .NET

In most, if not all, build systems, chunks of work executed during the build process can be referred to as tasks. As with most build tools, MSBuild provides quite a few tasks out of the box. There is also the MSBuildCommunityTasks library that contains some additional tasks. Occasionally you may find that you need to perform a task outside of what is already available. That's where the ability to create custom tasks becomes useful.

Boilerplate

The easiest approach to writing a custom MSBuild task is to derive your custom task class from Microsoft.Build.Utilities.Task and override the execute method.

/// CustomTask.cs
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace CreativeWizardry.Build.Tasks
{
    /// <summary>
    /// Execute a custom tasks that will log a simple message
    /// </summary>
    public class CustomTask : Task
    {
        // Optional property
        public string Prop { get; set; }

        // Required property indicated by Required attribute
        [Required]
        public string RequiredProp { get; set; }

        /// <summary>
        /// This method is called automatically when the task is run.
        /// </summary>
        /// <returns>Boolean to indicate if the task was sucessful.</returns>
        public override bool Execute()
        {                               
            Log.LogCommandLine(Prop);
            Log.LogCommandLine(RequiredProp);                  
            return true;
        }                    
    }
}

Running The Custom Task

Compile the custom task and copy the DLL into your MSBuild project directory. Below is an example of how to reference the DLL and execute the task.

<?xml version="1.0" encoding="utf-8"?>  
<UsingTask AssemblyFile="CreativeWizardry.Build.Tasks.dll" TaskName="CreativeWizardry.Build.Tasks.CustomTask" />
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Build">
        <CustomTask Prop="Optional Prop Value" RequiredProp="Required Prop Value" />
    </Target>
</Project>

The UsingTask property indicates the path — full or relative — to the assembly file. Since the DLL has been copited into the root of project folder, only the filename is needed. The TaskName is the name of the task to reference from the assembly. It is recommended that the full namespace is used for the TaskName but it not required. The following would also work, assuming there are not multiple tasks named CustomTask in the assembly.

<?xml version="1.0" encoding="utf-8"?>  
<UsingTask AssemblyFile="CreativeWizardry.Build.Tasks.dll" TaskName="CustomTask" />
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Build">
        <CustomTask Prop="Optional Prop Value" RequiredProp="Required Prop Value" />
    </Target>
</Project>

Disclaimer: The opinions expressed here are my own personal opinions and do not represent my employer's view in any way.