Using web.config transforms with App.config files

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.

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.

  1. Add App.config and App.Release.config to your project and fill them with content given above..
  2. Unload console application project.
  3. Right-click on project name and select “Edit <project file name>”.
  4. Project file is opened as XML-file and you can see what is inside it.
  5. Before closing tag of first property group add the following line:
    <ProjectConfigFileName>App.Config</ProjectConfigFileName>
  6. 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
    >
  7. 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" />
  8. 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
    >
  9. 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.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    12 thoughts on “Using web.config transforms with App.config files

    • November 22, 2013 at 2:26 am
      Permalink

      Or you could just use Slow Cheetah

    • February 13, 2014 at 12:59 pm
      Permalink

      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

    • April 11, 2014 at 8:38 pm
      Permalink

      What about source control, deleting and renaming isn’t gonna cut it..

    • November 7, 2014 at 3:59 pm
      Permalink

      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?

    • November 8, 2014 at 5:13 pm
      Permalink

      How do you exactly deploy your project?

    • November 10, 2014 at 10:11 am
      Permalink

      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.

    • April 7, 2015 at 3:47 pm
      Permalink

      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:

    • April 7, 2015 at 3:49 pm
      Permalink

      Sorry it wasn’t very intuitive how to use code block:

      Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets"

    • Pingback:Deploying app.config transformation through NuGet packages – System Architect

    • July 17, 2017 at 7:47 pm
      Permalink

      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.

    • April 14, 2020 at 5:41 pm
      Permalink

      Target tag is not closed?

    Leave a Reply

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