Hi folks
Sometimes you may want to perform some operations during build which are impossible or at least too difficult to perform using vanilla MSBuild.
For that purpose you may want to use custom task.
The simplest usage would look like
<UsingTask
TaskName="MyCoolAssembly.MyCoolTask"
AssemblyFile="MyCoolAssembly.dll"
/>
<Target
Name="MyCoolTarget">
<MyCoolTask />
</Target>
It can be made more complex and pass addition parameters and even define output parameters. But that is not the topic of this blogpost. Read MSBuild documentation if you want to know more.
I would like to discuss one thing that annoys me.
MSBuild loads custom assembly dll into its main AppDomain and therefore this assembly becomes locked until MSBuild exited. So by default after compilation completed MyCoolAssembly.dll couldn’t be removed until Visual Studio (or command prompt) reopened.
There are some workarounds you may find in questions like this http://stackoverflow.com/questions/13510465/the-mystery-of-stuck-inactive-msbuild-exe-processes-locked-stylecop-dll-nuget
But I’d prefer a solution which would work regardless of the way MSBuild called.
And recently I invented a way to solve this problem
<PropertyGroup>
<TempFolder>$([System.IO.Path]::GetTempPath())$([System.Guid]::NewGuid())</TempFolder>
</PropertyGroup>
<Target
Name="CopyTaskAssemblyToTempFolder"
BeforeTargets="BeforeBuild">
<Copy
SourceFiles="$(MSBuildThisFileDirectory)MyCoolAssembly.dll"
DestinationFolder="$(TempFolder)"
/>
</Target>
<UsingTask
TaskName="MyCoolAssembly.MyCoolTask"
AssemblyFile="$(TempFolder)\MyCoolAssembly.dll"
/>
<Target
Name="MyCoolTarget">
<MyCoolTask />
</Target>
Here my dll is being copied to the unique temp folder and then loaded and executed from there.
Well, ideally the dll should be removed after execution but to mark dll for deletion we’ll need to P/Invoke MoveFileEx which is too complicated to put into MSBuild script. So my solution will litter into the temp folder a bit but I think it is not that big deal.
Stay tuned