MSBuild-2 :👈 👉:MSBuild-4

Day 3 – MSBuild Targets and Tasks

Day 3 – MSBuild Targets and Tasks

Today you will learn how MSBuild executes Targets, how targets depend on each other, how BeforeTargets and AfterTargets work, and how to use built-in MSBuild Tasks. You will also create a simple custom task in C#.

1. What Is a Target?

A target is a named group of steps MSBuild executes. Targets contain tasks. You can invoke a target manually or let MSBuild run it as part of the build pipeline.

<Target Name="SayHello">
    <Message Text="Hello from MSBuild!" />
</Target>

Run it using:

dotnet build -t:SayHello

2. Target Dependencies

A target can depend on other targets using the DependsOnTargets attribute. MSBuild will run dependencies first.

<Target Name="Prepare">
    <Message Text="Preparing..." />
</Target>

<Target Name="BuildCustom" DependsOnTargets="Prepare">
    <Message Text="Building custom target..." />
</Target>

Running dotnet build -t:BuildCustom prints:

Preparing...
Building custom target...

3. BeforeTargets and AfterTargets

These attributes allow you to inject logic before or after an existing target, without modifying the original target.

<Target Name="BeforeCompile" BeforeTargets="Compile">
    <Message Text="Running before Compile..." />
</Target>

<Target Name="AfterCompile" AfterTargets="Compile">
    <Message Text="Running after Compile..." />
</Target>

This is very useful for:

  • running code generation before compile
  • logging or copying files after build
  • version stamping

4. Common Built-In MSBuild Tasks

Tasks are "commands" executed inside a target. Some common tasks:

  • Message – print text
  • Copy – copy files
  • Delete – delete files
  • MakeDir – create directories
  • Exec – run external commands

Copy example:

<Target Name="CopyFiles">
    <Copy
        SourceFiles="@(Image)"
        DestinationFolder="output\images" />
</Target>

Exec example:

<Target Name="RunScript">
    <Exec Command="echo Running script..." />
</Target>

5. Passing Properties and Items to Tasks

Tasks can receive inputs using properties and items.

<Target Name="ShowInfo">
    <Message Text="Framework: $(TargetFramework)" />
    <Message Text="Files: @(Image)" />
</Target>

6. Writing a Simple Custom Task (C#)

You can create your own MSBuild task in a C# class library.

Step 1: Create a class

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

public class HelloTask : Task
{
    public override bool Execute()
    {
        Log.LogMessage("Hello from custom task!");
        return true;
    }
}

Step 2: Use it in MSBuild

<UsingTask 
    TaskName="HelloTask"
    AssemblyFile="MyCustomTasks.dll" />

<Target Name="RunHelloTask">
    <HelloTask />
</Target>

7. Target Execution Flow (Simple Diagram)

[Prepare] ----> [Compile] ----> [Pack] ----> [Publish]

Using:
- DependsOnTargets
- BeforeTargets
- AfterTargets

8. Hands-On Exercise (10 minutes)

Add the following to your .csproj:

<Target Name="CleanTemp" BeforeTargets="Build">
    <Message Text="Cleaning temp folder..." />
    <MakeDir Directories="temp" />
</Target>

<Target Name="AfterBuildMessage" AfterTargets="Build">
    <Message Text="Build finished successfully!" />
</Target>

Run:

dotnet build

You should see the two custom messages before and after the build.

9. Summary

  • Targets are units of MSBuild execution.
  • Dependencies chain targets together.
  • BeforeTargets and AfterTargets let you extend existing targets.
  • Tasks do the actual work.
  • You can write your own tasks in C#.

10. Day 4 Preview

Tomorrow we cover SDK-style project structure, implicit imports, Directory.Build.props / Directory.Build.targets, and multi-targeting.

Back to Index
MSBuild-2 :👈 👉:MSBuild-4
*