MSBuild extension points
This article is a part of MSBuild series. Here is a list of all articles in this series:
- MSBuild basics for Sitecore devs
- MSBuild extension points
- MSBuild Build and Publish pipelines
- How to extend MSBuild publish pipeline to copy content files from all Helix modules to the output.
- How to extend MSBuild publish pipeline to apply transform files.
- How to extend MSBuild to execute Unicorn Sync action.
- VIDEO: Speed comparison of gulp vs MSBuild build & publish.
- How to extend MSBuild to copy indirect references.
- VIDEO: How to configure local development environment step by step
- VIDEO: How to set up Build & Release pipelines on VSTS step by step (the easiest way)
- How to extend MSDeploy with custom providers for Unicorn and Transform Files
- VIDEO: How to set up Build & Release pipelines on VSTS step by step (to generate WDP package, apply transform files and sync unicorn by MSDeploy)
- Helix Publishing Pipeline by Richard Szalay
MSBuild
offers a few ways you can extend build and publish process with your custom code. It's not a complete list but just a summary of the most useful techniques.
Import
This is the most common technique. You probably saw it many times in your .csproj
file. This is how the new Class Library project looks like:
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> ... <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> </Project>
The project imports Microsoft.Common.props
and Microsoft.CSharp.targes
. There is a chain of nested imports, but at the end, this is where the Clean
, Build
and Rebuild
targets are defined. You can add your own imports into .csproj
file to load your custom code.
Import from Nuget package
This is the same as above. You can create a NuGet package that contains .targets
file, build it with a -Tool
parameter, and when you install that package in your project, the <Import>
will be added automatically to your project file. If you want to see the real example, take a look at the source code of my Unicorn.MSBuild package. If you install it in your project, you will automatically get import like this at the end of the project file:
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> .. <Import Project="..\packages\Unicorn.MSBuild.1.0.0\build\Unicorn.MSBuild.targets" Condition="Exists('..\packages\Unicorn.MSBuild.1.0.0\build\Unicorn.MSBuild.targets')" /> </Project>
You can read how I implemented Unicorn.MSBuild
package in this article in this series.
Directory.Build.props and Directory.Build.targets
The Directory.Build.props
and Directory.Build.targest
are user-defined files that provide customisation to projects under a directory. If you put that files in your project location, the files will be loaded automatically. If the file is not there, MSBuild
would search the directory structure upward until it locates the files.
This is very useful if you want to set some properties or add some targets for your all projects, or projects under foundation folder for example.
.wpp.targets file
If you create a new Web Application project at the end of the file you will get additional imports:
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
One of these two lines will be executed, and it will import the Microsoft.Web.Publishing.targets
file. This file then will try to import the <projectname>.wpp.targets
file from the folder that holds your .csproj
. The file settings and extensions defined there will be applied automatically to your all publishing profiles.
I want more
The best way to learn more is to read the official documentation. Here are a few interesting pages:
Also, read my next article in this series where I described two ways to extend Build and Publish pipeline.