Custom MSBuild Task Development with Visual C++
Using the HardLinkTask
To add the HardLinkTask to a MSBuild project file, the task first needs to be imported so that it is in scope for the build process. This is accomplished through the UsingTask element:
<UsingTask TaskName="HardLinkTask" AssemblyName = "HardLinkTask, Version=126.96.36.199, Culture=neutral, PublicKeyToken=a912dca8b5fb92f0"/>
MSBuild uses the standard .NET assembly loading infrastructure, which means that a Task-implementing assembly can be specified in a vcxproj build file using either a path or using a fully qualified name for a GAC-housed assembly. In the example above, a GAC-located is used.
<Target Name="CreateHardLink"> <HardLinkTask SourceFileName="$(HardLinkSource)" TargetFileName="$(HardLinkTarget)"/> </Target>
The final piece of the puzzle is to add a PropertyGroup element to store the properties that need to be passed into the task:
<PropertyGroup> <HardLinkSource>C:\source.txt</HardLinkSource> <HardLinkTarget>C:\destination.txt</HardLinkTarget> </PropertyGroup>
The target then can be executed by invoking MSBuild from the command line and using the /t switch to specify the target name:
msbuild MyApp.vcxproj /t:CreateHardLink
MSBuild custom tasks allow any arbitrary managed code to be executed as part of the build process. C++/CLI is the managed language that offers the easiest access to native functionality, and as many custom MSBuild tasks will be written to access functionality only available through native APIs, C++/CLI is a great language for custom task development.
The Windows SDK CreateHardLink function allows hard links to be created to a file. Hard links are an additional directory entry to an existing file, and allow a virtual copy operation to take place. Creating a hard-link MSBuild task in C++/CLI is a simple matter of capturing two properties to store the source and destination file name, converting these to the appropriate string data type for calling CreateHardLink, and calling this method during the tasks Execute method. Once the task is completed and compiled, it can be added to an MSBuild file target ready for employment during the build process.
About the Author
Nick Wienholt is an independent Windows and .NET consultant based in Sydney. He is the author of Maximizing .NET Performance and co-author of A Programmers Introduction to C# 2.0 from Apress, and specialises in system-level software architecture and development, with a particular focus of performance, security, interoperability, and debugging.
Nick is a keen and active participant in the .NET community. He is the co-founder of the Sydney Deep .NET User group and writes technical articles for Australian Developer Journal, ZDNet, Pinnacle Publishing, CodeGuru, MSDN Magazine (Australia and New Zealand Edition) and the Microsoft Developer Network. An archive of Nick's SDNUG presentations, articles, and .NET blog is available at www.dotnetperformance.com. In recognition of his work in the .NET area, he was awarded the Microsoft Most Valued Professional Award from 2002 through 2007.
Page 2 of 2