Customizing the MSBuild file

Customizing the MSBuild file

In this post we are going to edit and customize the default .csproj file and see our first MSBuild program in action. This post is a continuation of my previous post Introduction to MSBuild.

Prerequisites

Before we take a dive into editing our default project please make sure that the MSBuild Tools is installed and the 'PATH' is set in the environment variables for MSBuild.exe to be detected by our command prompt. We would be using .NET 6 but you can use any .NET Framework of your choice. You might have to do some extra configurations if the Visual Studio is not already installed in your system and you want you continue without installing it.

  1. Install Code Editor of your choice how we would be going ahead with Visual Studio Code
  2. Install the Visual Studio Build Tools
  3. Install .NET SDK

Creating a console app with dotnet CLI

Create a directory with the following command
mkdir MSBuildDemoApp
Navigate to the directory
cd MSBuildDemoApp
Create a console app with the name same as that of the directory
dotnet new console

This would successfully create a console app in the directory MSBuildDemoApp.

Customizing the MSBuild file

Open the folder with Visual Studio Code and open the .csproj file. This file is the MSBuild file which we would be customizing and executing it with the help of MSBuild.exe.

The MSBuild files would contain the code mentioned below -

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

You file may look different if you have create the console app in .NET Framework instead of .NET Core or .NET( 5 and above.) The default file just defines some default properties that can be access which the program. Let us now modify our .csproj file to contain the below mentioned code.

<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="DisplayText">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <Target Name="DisplayText">
    <Message Text="Hello World!!!"/>
  </Target>
</Project>

All we have done here is defined a Target named "DisplayText" and invoked a Task for Message and assigned the Text as "Hello World".
Let us now run our program from the command prompt or VSCode Terminal window by the below command

msbuild

This command will look for the file with extension .csproj and try to execute it. As the first line of the files specifies
a DefaultTargets="DisplayText" MSBuild will invoke the target and display the message "Hello World!!!" on the console.

Now let us try to display a Text defined in the PropertyGroup of csproj file. First add a new propertygroup and define a "Username"
property in it as shown below-

  <PropertyGroup>
    <Username>John</Username>
  </PropertyGroup>

Now we will use the property defined above in our Message Task defined under the "DisplayText" target. The modified code would
look like below -

<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="DisplayText">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <PropertyGroup>
    <Username>John</Username>
  </PropertyGroup>
  <Target Name="DisplayText">
    <Message Text="Hello $(Username)!!!"/>
  </Target>
</Project>

Execute the file again with the command msbuild and watch the text getting displayed from our Username property as
"Hello John!!!" on the console.

Similary we can defined multiple message task or any task inside the target. Let us also display the Target Framework use the
predefined property TargetFramework

<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="DisplayText">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <PropertyGroup>
    <Username>John</Username>
  </PropertyGroup>
  <Target Name="DisplayText">
    <Message Text="Hello $(Username)!!!"/>
    <Message Text="Target Framework $(TargetFramework)."/>
  </Target>
</Project>

You might have noticed that the properties are accessed using the syntax $(PropertyName). Executing the above code would
also display the text "Target Framework net6.0." giving the final output as -

Hello John!!!
Target Framework net6.0.

We have thus customized our first MSBuild file using a Target, Message Task and Property. We can do pretty much anything
with the customization of the csproj using the wide variety of Tasks provided by Microsoft.
The Targets can be chained one after the other and could also be injected inside the build process to do custom
activities.

Thank you for reading and see you in the next post !

Buy a coffee for sudshekhar