首页 文章

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

提问于
浏览
102

我有一个包含MSTest集成测试的 dll-type project . 在我的机器上测试通过,我希望在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

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

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

10 回答

  • 9

    您可以尝试以下方法:

    • 在Solution Explorer中右键单击项目,然后选择 Unload Project .

    • 项目将被卸载 . 再次右键单击该项目,然后选择 Edit <YourProjectName>.csproj .

    • 现在可以在Visual Studio中编辑项目文件 .

    • 在* .csproj文件中找到包含应用程序配置文件的位置 . 它看起来像:

    <ItemGroup>
            <None Include="App.config"/>
        </ItemGroup>
    
    • 用以下内容替换此行:
    <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
            <None Include="App.Debug.config"/>
        </ItemGroup>
    
        <ItemGroup Condition=" '$(Configuration)' == 'Release' ">
            <None Include="App.Release.config"/>
        </ItemGroup>
    

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

  • 23

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

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

    "Hold on", - 你可能会说,“但我需要这个用于我的集成/单元测试,而且它是一个库!” . 这是真的,这是你可以做的(只选一个,不要混合):

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

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

    • 安装SlowCheetah并重新启动Visual Studio(Visual Studio>工具>扩展和更新...>在线> Visual Studio库>搜索"Slow Cheetah")

    • 定义您的解决方案配置(默认情况下是Debug和Release),您可以添加更多(右键单击解决方案资源管理器中的解决方案> 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配置,则在构建之后的输出文件夹中,您将找到从 Config\App.Debug.config 复制并随后重命名的PatternPA.Test.Integration.dll.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>
    
  • 143

    你应该考虑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)开关指定的生成的配置 .

  • 11

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

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

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

  • 1

    我正在使用XmlPreprocess tool进行配置文件操作 . 它使用一个映射文件用于多个环境(或者在您的情况下为多个构建目标) . 您可以通过Excel编辑映射文件 . 这是非常容易使用 .

  • 1

    来自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>
    

    这适用于Web项目:

    <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>
    
  • 3

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

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

  • 0

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

    简而言之,他们声明:“通过添加后期构建事件 . [...]我们需要添加以下内容:

    if "Debug"=="$(ConfigurationName)" goto :nocopy
    del "$(TargetPath).config"
    copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
    :nocopy
    
  • 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>
    
  • 3

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

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

    希望这可以帮助 .

相关问题