Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

17 Mar 2008

Easily switching between App.Config files with MSBuild

Imagine the following situation: One codebase, two customers with different Application Configuration files. How can we easily switch between the different configurations? By taking advantage of the Build Configurations functionality in Visual Studio we can easily switch between different configurations

screenshot of the configuration manager in visual studio

A brute-force solution would be to add a Post-build Event that copies the desired App.Config file to the destination directory. In the Microsoft.Common.targets file (usually at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727) around line 725 you can read how MSBuild chooses the App.Config that is copied to the destination folder

Choose exactly one app.config to be the main app.config that is copied to the destination folder.
The search order is:

  1. Choose the value $(AppConfig) set in the main project.
  2. Choose @(None) App.Config in the same folder as the project.
  3. Choose @(Content) App.Config in the same folder as the project.
  4. Choose @(None) App.Config in any subfolder in the project.
  5. Choose @(Content) App.Config in any subfolder in the project.

Thus, simply setting $(AppConfig) should be enough to make sure that MSBuild chooses the appropriate App.Config file. Here is an example of a csproj section that defines $(AppConfig) as App.Customer1.Config or App.Customer2.Config depending on the choosen Build configuration

<propertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug Customer1|AnyCPU' "> 
	<debugSymbols>true</debugSymbols>
	<debugType>full</debugType>
	<optimize>false</optimize>
	<outputPath>bin\Debug\</outputPath>
	<defineConstants>DEBUG;TRACE</defineConstants>
	<errorReport>prompt</errorReport>
	<warningLevel>4</warningLevel>
	<appConfig>App.Customer1.Config</appConfig> 
</propertyGroup> 
<propertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug Customer2|AnyCPU' "> 
	<debugSymbols>true</debugSymbols>
	<outputPath>bin\Debug Customer2\</outputPath>
	<defineConstants>DEBUG;TRACE</defineConstants>
	<debugType>full</debugType> <platformTarget>AnyCPU</platformTarget> <codeAnalysisUseTypeNameInSuppression>true</codeAnalysisUseTypeNameInSuppression>
	<codeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</codeAnalysisModuleSuppressionsFile>
	<errorReport>prompt</errorReport>
	<appConfig>App.Customer2.Config</appConfig> 
</propertyGroup>