In one of my projects I needed configuration transforms similar to web applications. But I needed transforms for command line and Windows service applications to make sure that with release builds some settings are different (by example, web service URL-s and some other settings). I found some materials from web and got everything work well. Here is how to enable web.config transforms for App.config files too.
Configuration transforms
We can use configuration transforms also with other project types if we make some modifications to project files. We still use the same transformation engine as web applications and therefore we have no new rules to study.
- Visual Studio 2010: Web.config transforms (by me)
- Applying XDT magic to App.Config (Vishal Joshi’s blog)
NB! Steps listed below and XML-blocks are tested on Visual Studio 2012 only. They should also work for Visual Studio 2013. My version here solves also one problem I found from Vishal’s XML- file name of configuration for vshost version of compiled executable. Practically you can take the code here with copy-paste and you don’t have to worry about hardcoded project names.
App.config transforms
To test if transforms work you have to use real transforms. Insert-transform with appSettings block is maybe simplest one. I tested with following configuration files.
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="FirstName" value="Gunnar"/>
</appSettings>
</configuration>
App.Release.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="LastName" value="Peipman" xdt:Transform="Insert"/>
</appSettings>
</configuration>
Configuration file after transform:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="FirstName" value="Gunnar"/>
<add key="LastName" value="Peipman"/>
</appSettings>
</configuration>
Making App.config transforms work
Let’s see how to do it with console application.
- Add App.config and App.Release.config to your project and fill them with content given above..
- Unload console application project.
- Right-click on project name and select “Edit <project file name>”.
- Project file is opened as XML-file and you can see what is inside it.
- Before closing tag of first property group add the following line:
<ProjectConfigFileName>App.Config</ProjectConfigFileName>
- Find <ItemGroup> where App.Config is defined (<None Include=”App.Config” />) and add the following block after App.Config node:
<None Include="App.Release.config">
<DependentUpon>App.Config</DependentUpon>
</None> - Find first <Import Project= node and add the following import as last one to list:
<Import Project="$(VSToolsPath)\Web\Microsoft.Web.Publishing.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" Condition="false" /> - To the end of file, just before </Project> tag, paste the following block of code:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
<TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
<ItemGroup>
<AppConfigWithTargetPath Remove="app.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetName).vshost$(TargetExt).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target> - Save project file, close it and reload it.
When loading project again Visual Studio may ask you about some modifications to file so all versions from Visual Studio 2010 to current are able to use your project file with no modifications to it. Agree with it because then you don’t have dependencies to Visual Studio versions.
Conclusion
It is easy to enable web.config transforms also for App.config files but still it needs some manual work. We have to modify application configuration file manually and if needed let Visual Studio to make its own modifications to file. Although the process this far seems close to hacking everything still works nice and Visual Studio is able to understand and use transformed configurations well.
View Comments (11)
Or you could just use Slow Cheetah
This helped me a lot, but, there is always a but with M$ :) ...
Is there any way to make VS show 'Preview Transform' right click menu option like for web.config?
Thanks in advance
Cheers
I just saw Alec Whittington comment and found out that SlowCheetah (http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5) is a way to go.
Thanks
What about source control, deleting and renaming isn't gonna cut it..
nice artical on console app config transformations..
But, I am looking for solution that helps in deployment process. Like we have dev, integration, test, .. environments. And, we want to have config transformations for each of these environments.
ex: app.dev.config, app.test.config ..
I tried out above solution but doesn't works this scenario. Any thoughts?
How do you exactly deploy your project?
I am working on WebJob which is console app and deployment is using the default webjob publish wizard which does not indicate anything about environment.
Currently, I am trying to use msbuild script to automate.
Thank you Gunnar, very nice article, but it might not work in newer VS versions. Suggest to consider to use $(VisualStudioVersion) variable rather than hard-coding particular VS version, e.g:
Sorry it wasn't very intuitive how to use code block:
Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets"
Hеlⅼߋ there, Yօu've done an incгedible job.
Iwill ϲertainlү digg it and personally recommend to mmy
friends. I am ѕurre they will be benefited from this site.
Target tag is not closed?