Code Scraps: Add a custom transformation file to an MSBuild project

Visual Studio has offered a neat feature for transforming config files for Web Applications for years – that’s where you have a default web.config file, and then a web.<something>.config for each build configuration in your project. By default usually web.Debug.config and web.Release.config.

But what if you want your normal desktop application to have the same transformation capabilities on the app.config file? There are plugins you can get for Visual Studio that can do this which make it easier if you have a big solution with multiple projects, but for a single Project solution the easiest way is to add the functionality manually to your csproj Project file yourself.

Open your csproj file in a text editor, and copy the following at the end of the project – just before the closing </project> tag.

<UsingTask TaskName=”TransformXml” AssemblyFile=”$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll” />
<Target Name=”App_config_AfterCompile” AfterTargets=”AfterCompile” Condition=”Exists(‘App.$(Configuration).config’)”>
<TransformXml Source=”App.config” Destination=”$(IntermediateOutputPath)$(TargetFileName).config” Transform=”App.$(Configuration).config” />
<ItemGroup>
<AppConfigWithTargetPath Remove=”@(AppConfigWithTargetPath)” />
<AppConfigWithTargetPath Include=”$(IntermediateOutputPath)$(TargetFileName).config”>
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target>
<Target Name=”App_config_AfterPublish” AfterTargets=”AfterPublish” Condition=”Exists(‘App.$(Configuration).config’)”>
<PropertyGroup>
<DeployedConfigFile>$(_DeploymentApplicationDir)$(TargetName)$(TargetExt).config$(_DeploymentFileMappingExtension)</DeployedConfigFile>
</PropertyGroup>
<Copy Condition=”Exists(‘$(DeployedConfigFile)’)” SourceFiles=”$(IntermediateOutputPath)$(TargetFileName).config” DestinationFiles=”$(DeployedConfigFile)” />
</Target>

Along with XML transformation, you can also add your own file substitution transformations based on build configuration. I often have additional config files that I want to customise per build, and you can do this with some clever AfterBuild events. In the example below, I have a “properties.json” file in a project.

<Target Name=”properties_json_AfterBuild” AfterTargets=”AfterBuild” Condition=”Exists(‘properties.$(Configuration).json’)”>
<Copy Condition=”Exists(‘properties.$(Configuration).json’)” SourceFiles=”properties.$(Configuration).json” DestinationFiles=”$(OutputPath)properties.json” />
</Target>

So for example, when building the Release configuration for my project, this AfterBuild event will use a file called properties.Release.json in the project directory and place it in the build output folder as bin\Release\properties.json.

You can use this simple transformation logic for any type of file – text or binary.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.