For the TraceEtw project I needed to generate code (headers, manifests, etc.) during the build and have the build consume those files on the fly. It turns out that Visual Studio C++ projects (.vcxproj) and MSBuild support a high level of customization for both the build process and the IDE UI. Moreover, this customization is all contained in the project files so it can be neatly packaged using NuGet to make it reusable. This blog brings together the various pieces needed to make that work.
Customization begins by defining a new file extension (say .epx) and associate it with a content type in an XML config file (here called EventProvider.xml):
This piece of XML associates the .epx file extension with the
<EventProvider> item element in MSBuild project files.
The XML file is referenced either in a .targets file (for later reuse and NuGet packaging) or in the VS project itself (for one-time use):
For NuGet packaging the .targets file needs to have the same name as the package ID so that NuGet adds it to the build project during package install. In NuGet’s .nuspec config file, the .targets file is placed in the build folder:
At that point, when an .epx file gets added to the project it is assigned its own
<EventProvider> item element instead of some the usual
This allows referencing those files as
@(EventProvider) lists in MSBuild targets and customizing their processing.
Visual Studio also allows the definition of custom UI property pages to give more control over the build to users without having them edit the build project XML:
This is achieved by adding a
<Rule> element under
<ProjectSchemaDefinitions> in the first XML file mentioned in this blog:
This piece of XML defines a boolean property called ‘Verbose’ that appears in the ‘General’ property page of files whose content type is ‘EventProvider’. When the user modifies that property its new value gets attached to the existing
<EventProvider> element in the build project:
The property value is retrieved using
%(EventProvider.Verbose) in MSBuild targets:
For full code samples, see the following files on GitHub: