Adding and removing build targets from NuGet powershell

1. May 2013 15:56 by admin in .net, msbuild, nuget
In NuGet packages you can add powershell scripts to alter the .csproj file of the project in which your package is installed. Recently I had quote some trouble getting this exactly right but nailed it in the end. So here's a sample to share with google so I can find it later ;) This sample adds a target that runs after the AfterBuild target: The Get-Project and Get-MSBuildProject are from the nuget powertools by David Fowlder. (This script is part of the install.ps1 script from a open source project called Weld).

Adding a build target to a project

$project = Get-Project
$buildProject = Get-MSBuildProject
$target = $buildProject.Xml.AddTarget("WeldAfterbuild")
$target.AfterTargets = "AfterBuild"
$task = $target.AddTask("Exec")
$task.SetParameter("Command", "`".\..\packages\Weld.1.0.0\tools\Weld.console`" bin\`$(TargetFileName) `"`$(ProjectDir)\Scripts\Weld`"")
$project.Save() #persists the changes
Notice how the ` (backtick) is used to escape the " and $ characters. This result in the .csproj like this:
<Target Name="WeldAfterbuild" AfterTargets="AfterBuild">
<Exec Command="&quot;.\..\packages\Weld.1.0.0\tools\Weld.console&quot; bin\$(TargetFileName) &quot;$(ProjectDir)\Scripts\Weld&quot;" />
</Target>
This effectively calls the Weld.Console application passing it the current project .dll name and a target folder.

Removing a build target from a project

In uninstall.ps1 we can remove the same target like this:
$project = Get-Project
$buildProject = Get-MSBuildProject
$projectRoot = $buildProject.Xml;
Foreach ($target in $projectRoot.Targets)
{
If ($target.Name -eq "WeldAfterbuild")
{
$projectRoot.RemoveChild($target);
}
}
$project.Save() #persists the changes
Basically we search for target called "WeldAfterbuild" and then remove that from the project! Easy once you know how :)