如何为多个构建配置选择不同的app.config

时间:2011-11-10 16:17:28

标签: .net visual-studio configuration continuous-integration release-management

我有一个包含MSTest集成测试的 dll类型项目。在我的机器上测试通过,我希望在CI服务器上发生同样的事情(我使用TeamCity)。但是测试失败了,因为我需要在app.config中调整一些设置。这就是为什么我想要一个单独的第二个app.config文件来保存CI服务器的设置。

所以我想

/Sln
 /Proj
  app.config (I think this is required by VS)
  app.Release.config (This is a standalone independent config file)

因此,如果我在CI上的构建配置中选择Release配置,我想使用app.Release.config文件而不是app.config

问题
对于简单的.dll类型项目,这似乎并不简单。对于Web项目,我可以进行Web配置转换。我找到了一个黑客如何为dll类型的项目进行这些转换,但我不是黑客的忠实粉丝。

问题
什么是根据.NET项目的构建配置调整app.config文件的标准方法(例如Debug,Release,...)?

10 个答案:

答案 0 :(得分:150)

使用SlowCheetah插件。有关如何使用SlowCheetah继续阅读的更多选项和详细信息。

正如您已经注意到的,没有默认的简单方法可以为库类型(.dll)项目使用不同的配置文件。原因是目前的想法是:“你不需要”!框架开发人员认为您需要配置可执行文件:无论是控制台,桌面,Web,移动应用程序还是其他内容。如果您开始为 dll 提供配置,您可能会得到一些我称之为 config hell 的内容。您可能不再(轻易地)理解为什么这个和那些变量看起来似乎无处可见。

“坚持”, - 你可能会说,“但我需要这个用于我的集成/单元测试,是一个库!”。这是真的,这就是你能做的(只选一个,不要混合):

1。 SlowCheetah - 转换当前配置文件

您可以安装SlowCheetah - 一个Visual Studio插件,为您执行所有低级XML戳(或转换)。它的工作方式,简要说明:

  • 安装SlowCheetah并重新启动Visual Studio(Visual Studio>工具>扩展和更新...>在线> Visual Studio图库>搜索“慢速猎豹”)
  • 定义您的解决方案配置(默认情况下 Debug Release ),您可以添加更多(右键单击 Solution Explorer中的解决方案> Configuration Manager ... > Active Solution Configuration > New ...
  • 根据需要添加配置文件
  • 右键单击配置文件> 添加转换
    • 这将创建转换文件 - 每个配置一个
    • 转换文件作为注入器/更改器工作,它们在原始配置文件中找到所需的XML代码并注入新行或改变所需的值,无论你告诉它做什么

2。摆弄.proj文件 - 复制 - 重命名一个全新的配置文件

最初来自here。这是一个自定义的MSBuild任务,您可以将其嵌入到Visual Studio .proj 文件中。将以下代码复制并粘贴到项目文件

<Target Name="AfterBuild">
    <Delete Files="$(TargetDir)$(TargetFileName).config" />
    <Copy SourceFiles="$(ProjectDir)\Config\App.$(Configuration).config"
          DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>

现在在名为Config的项目中创建一个文件夹并在其中添加新文件: App.Debug.config App.Release.config 等等。现在,根据您的配置,Visual Studio将从Config文件夹中选择配置文件,并将其复制重命名为输出目录。因此,如果您选择了 PatternPA.Test.Integration 项目并选择了 Debug 配置,则在构建之后的输出文件夹中,您将找到 PatternPA.Test.Integration。 dll.config 文件,该文件是从Config\App.Debug.config复制并在之后重命名的。

这些是您可以在配置文件中留下的一些注释

<?xml version="1.0" encoding="utf-8"?>
<configuration>

    <!-- This file is copied and renamed by the 'AfterBuild' MSBuild task -->

    <!-- Depending on the configuration the content of projectName.dll.config 
        is fully substituted by the correspondent to build configuration file 
        from the 'Config' directory. -->

</configuration>

在Visual Studio中,您可以使用类似的内容

Project structure

3。使用Visual Studio外部的脚本文件

每个构建工具(如NAntMSBuild)将提供根据配置转换配置文件的功能。如果您在构建计算机上构建解决方案,这将非常有用,您需要更好地控制准备产品的内容和方式。

例如,您可以使用web发布dll的任务来转换任何配置文件

<UsingTask AssemblyFile="..\tools\build\Microsoft.Web.Publishing.Tasks.dll"
    TaskName="TransformXml"/>

<PropertyGroup>
    <!-- Path to input config file -->  
    <TransformInputFile>path to app.config</TransformInputFile>
    <!-- Path to the transformation file -->    
    <TransformFile>path to app.$(Configuration).config</TransformFile>
    <!-- Path to outptu web config file --> 
    <TransformOutputFile>path to output project.dll.config</TransformOutputFile>
</PropertyGroup>

<Target Name="transform">
    <TransformXml Source="$(TransformInputFile)"
                  Transform="$(TransformFile)"
                  Destination="$(TransformOutputFile)" />
</Target>

答案 1 :(得分:22)

您可以尝试以下方法:

  1. 在解决方案资源管理器中右键单击项目,然后选择卸载项目
  2. 项目将被卸载。再次右键单击该项目,然后选择编辑&lt; YourProjectName&gt; .csproj
  3. 现在您可以在Visual Studio中编辑项目文件。
  4. 在* .csproj文件中找到包含应用程序配置文件的位置。它看起来像:
  5.     <ItemGroup>
            <None Include="App.config"/>
        </ItemGroup>
    
    1. 将以下行替换为:
    2.     <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
              <None Include="App.Debug.config"/>
          </ItemGroup>
      
          <ItemGroup Condition=" '$(Configuration)' == 'Release' ">
              <None Include="App.Release.config"/>
          </ItemGroup>
      

      我没有尝试过app.config文件的这种方法,但它适用于其他Visual Studio项目。您可以以您喜欢的任何方式自定义构建过程。无论如何,让我知道结果。

答案 2 :(得分:12)

您应该考虑ConfigGen。它是为此目的而开发的。它根据模板文件和设置文件为每个部署机器生成配置文件。我知道这并没有具体回答你的问题,但它可能很好地回答了你的问题。

因此,不是调试,发布等,您可能有测试,UAT,生产等。您还可以为每台开发人员机器设置不同的设置,以便您可以生成特定于您的开发机器的配置并更改它而不会影响任何一个人的部署。

使用示例可能是......

<Target Name="BeforeBuild">
    <Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t       
        $(ProjectDir)App.config.template.xml -o $(SolutionDir)ConfigGen" />

    <Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t
        $(ProjectDir)App.config.template.xml -l -n $(ProjectDir)App.config" />
</Target>

如果将其放在.csproj文件中,并且您有以下文件......

$(ProjectDir)App.Config.Settings.xls

MachineName        ConfigFilePath   SQLServer        

default             App.config      DEVSQL005
Test                App.config      TESTSQL005
UAT                 App.config      UATSQL005
Production          App.config      PRODSQL005
YourLocalMachine    App.config      ./SQLEXPRESS


$(ProjectDir)App.config.template.xml 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
   <configuration>
   <appSettings>
       <add key="ConnectionString" value="Data Source=[%SQLServer%]; 
           Database=DatabaseName; Trusted_Connection=True"/>
   </appSettings>
</configuration>

...那么这将是结果......

从第一个命令开始,为xls文件中指定的每个环境生成一个配置文件,放在输出目录$(SolutionDir)ConfigGen

.../solutiondir/ConfigGen/Production/App.config

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
   <configuration>
   <appSettings>
       <add key="ConnectionString" value="Data Source=PRODSQL005; 
           Database=DatabaseName; Trusted_Connection=True"/>
   </appSettings>
</configuration>

从第二个命令开始,dev计算机上使用的本地App.config将替换为本地(-l)开关和文件名(-n)开关指定的生成的配置。

答案 3 :(得分:10)

使用与Romeo相同的方法,我将其改编为Visual Studio 2010:

 <None Condition=" '$(Configuration)' == 'Debug' " Include="appDebug\App.config" />

 <None Condition=" '$(Configuration)' == 'Release' " Include="appRelease\App.config" />

在这里,您需要将两个App.config文件保存在不同的目录中(appDebug和appRelease)。 我测试了它,它工作正常!

答案 4 :(得分:3)

我正在使用XmlPreprocess tool进行配置文件操作。它正在为多个环境(或您的案例中的多个构建目标)使用一个映射文件。您可以通过Excel编辑映射文件。它非常易于使用。

答案 5 :(得分:3)

来自VisualStudio Gallery的SlowCheetah和FastKoala似乎是帮助解决这个问题的非常好的工具。

但是,如果你想避免插件或使用他们在整个构建/集成过程中更广泛地实现的原则,那么将它添加到你的msbuild * proj文件是一个简写修复。

注意:这或多或少是对@ oleksii答案第2号的修改。

这适用于.exe和.dll项目:

  <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
  </Target>

这适用于网络项目:

  <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
  </Target>

请注意,即使在构建正确开始之前,此步骤也会发生。配置文件的转换发生在项目文件夹中。因此,在调试时可以使用转换后的web.config(SlowCheetah的缺点)。

请记住,如果您创建App_Config文件夹(或您选择调用它的任何内容),各种中间配置文件应具有Build Action = None,并且Copy to Output Directory =不要复制。

这将两个选项组合成一个块。根据条件执行适当的一个。首先定义TransformXml任务:

<Project>
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Condition="Exists('App_Config\app.Base.config')" Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
    <TransformXml Condition="Exists('App_Config\Web.Base.config')" Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
</Target>

答案 6 :(得分:1)

查看XDT(web.config)转换引擎是否可以为您提供帮助。目前它仅在本地支持Web项目,但从技术上讲,没有什么能阻止您在其他应用程序类型中使用它。有许多关于如何通过手动编辑项目文件来使用XDT的指南,但我找到了一个非常有用的插件:https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

该插件仅帮助设置配置,不需要构建,并且可以在其他计算机或构建服务器上构建解决方案,而无需插件或任何其他工具。

答案 7 :(得分:1)

我用我在这里找到的解决方案解决了这个问题: http://www.blackwasp.co.uk/SwitchConfig.aspx

简而言之,他们所声明的是: &#34;通过添加构建后事件。[...]我们需要添加以下内容:

if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy

答案 8 :(得分:1)

我听说过有关SlowCheetah的好消息,但无法使其正常工作。我做了以下工作:为特定配置在每个标签上添加am标记。

例如:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'UAT|AnyCPU'">
    <OutputPath>bin\UAT\</OutputPath>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AppConfig>App.UAT.config</AppConfig>
  </PropertyGroup>

答案 9 :(得分:0)

经过一些关于管理开发和构建配置的研究后,我决定自己动手,我已经在bitbucket上提供了它:https://bitbucket.org/brightertools/contemplate/wiki/Home

这是多个环境的多个配置文件,它是一个基本的配置条目替换工具,可以使用任何基于文本的文件格式。

希望这有帮助。