如何为几种构建配置选择不同的app.config


115

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

所以我想有

/ Sln
 /项目
  app.config(我认为这是VS必需的)
  app.Release.config(这是一个独立的独立配置文件)

因此,如果我在CI的build config中选择Release configuration,我想使用app.Release.config文件而不是app.config

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

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

Answers:


154

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

正如您已经注意到的,对于库类型(.dll)项目,没有默认且简便的方法来使用不同的配置文件。原因是当前的想法是:“您不需要”!框架开发人员认为您需要配置可执行文件:控制台,桌面,Web,移动应用程序或其他。如果您开始为dll提供配置,则可能会遇到一些我可以称之为config hell的事情。您可能不再(轻松地)理解为什么这个变量和那个变量具有如此怪异的值,似乎无处不在。

“等等”,您可能会说,“但是我在集成/单元测试中需要它是一个库!”。没错,这就是您可以做的(仅选择一个,不要混用):

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

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

  • 安装SlowCheetah并重新启动Visual Studio(Visual Studio>工具>扩展和更新...>联机> Visual Studio Gallery>搜索“ Slow Cheetah”)
  • 定义解决方案配置(默认情况下有DebugRelease),您可以添加更多(在Solution Explorer > Configuration Manager ... > Active Solution Configuration > New ...中右键单击解决方案)
  • 根据需要添加配置文件
  • 右键单击配置文件> 添加转换
    • 这将创建转换文件-每个配置一个
    • 转换文件充当注入器/更改器,它们在原始配置文件中找到所需的XML代码,并注入新行或更改所需的值,无论您执行什么操作

2.修饰.proj文件-复制并重命名一个全新的配置文件

原来是从这里拿来的。这是一个自定义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.configApp.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中,您可以拥有类似的内容

项目结构

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>

您的第二个解决方案工作正常,但不适用于发布Web项目。发布ASP.NET项目后,将发布原始的web.config。
Massood Khaari 2014年

3
@MassoodKhaari,您需要确保为发布目标调用此任务。发布项目时,将调用一个单独的构建目标,默认情况下该AfterBuild目标可能不会调用。在典型的编译过程中AfterBuild,默认情况下将调用目标。对于发布案例,应该有一个快速解决方案
oleksii 2014年

1
使用了第二种方法(kinda)。转至项目属性,并编辑了BeforeBuild以将App.<Target>.configover 复制App.config项目dir中,而不是输出dir中。
SparK 2014年

@oleksii你是对的。但是我仍然找不到我的Web发布过程正在使用的目标(在Visual Studio 2013中)。
Massood Khaari 2014年

1
我正在使用第二种方法,但是需要在AfterBuild目标中添加条件以确保文件在删除之前确实存在。我有一个Debug构建配置,它基本上只使用默认的App.config文件,但是没有App.Debug.config,这意味着构建步骤将失败。我刚刚补充Condition="Exists('$(ProjectDir)App.$(Configuration).config')"
Siewers '16

23

您可以尝试以下方法:

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

    <ItemGroup Condition =“'$(配置)'=='发布'”>
        <None Include =“ App.Release.config” />
    </ ItemGroup>

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


Tnx的答案,但这不适用于app.config。app.config如果我使用VS build或Teamcity VS sln构建运行程序,则VS需要强制性的并且不会应用Release config。
oleksii 2011年

2
此处说明了操作方法
Gabrielizalo

1
为什么这个答案有那么多赞成票?我试过了,它不起作用。实际上,在调试和发布模式下都没有App.config文件,因此输出文件夹中没有对应的文件。App.Debug.config和App.Release.config文件对Visual Studio没有任何意义。
MarkusParker

它不起作用:.csproj无法打开,错误消息“目标元素外部的元素必须具有:包含,更新或删除”
Elo

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>

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


2
Tnx的答案,这看起来还不错。但是有一些缺点,它仅显示75次下载(因此不成熟),并且仅适用于.xls或.xlsx。我真的不想依靠另一种自定义文档格式来进行简单操作。我一直在寻找更标准的方法...
oleksii 2011年

2
公平的说,尽管它说在CodePlex上有194次下载,但xls是电子表格,几乎不是自定义格式,我知道有三家主要的投资银行已经批准使用此文件,所以如果它们对他们足够好...当前请求的功能之一是使用xml进行设置。它已经差不多准备好了,但是无论如何我还是更喜欢电子表格方法。在表格视图中查看每种环境的所有设置要容易得多
Daniel Dyson

现在,我们处于测试configGen版本的最后阶段,该版本可用于生成纯文本文件,而不仅仅是XML。因此,如果您想生成特定于环境的CSS,SQL,JavaScript等,请关注configGen站点
Daniel Dyson

感谢Daniel的解决方案,这正是我想要的。我会试试看。
巴普林德·辛格

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)中。我测试了它,效果很好!


3

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


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>

这适用于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,并且复制到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>


我只是在Visual Studio 2017中尝试过,但无法正常工作。射击。我真的希望它能起作用,因为它看起来最容易实现。
格雷格·伯格哈特

示例中未定义TransformXml任务。我要添加一个条目。您可以在mycustom.targets文件中定义它,该文件包含在解决方案的所有启动项目中。
埃尼奥拉

@GregBurghardt,您现在要尝试吗?
埃尼奥拉

我可以试试看。我为Visual Studio安装了Config Transform插件,并且效果很好。我实际上想知道插件是否基本上可以完成您的回答。
格雷格·伯格哈特

好吧,让我知道如何进行。
埃尼奥拉'18

1

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

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


现在应该是答案。刚刚在VS 2017上尝试过,它就像一个魅力。您不需要发布项目。只是建立它。对于我们的持续集成构建中使用的测试项目而言,它的工作效果非常好,因此我们可以以无头模式运行Selenium测试,但是在本地运行时会打开浏览器。+1,000,000,如果可以的话。
格雷格·伯格哈特

1

我已经通过在这里找到的解决方案解决了该主题:http : //www.blackwasp.co.uk/SwitchConfig.aspx

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

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

到目前为止,最简单的方法来完成应该是一个非常简单且必不可少的功能,而这种功能却被思想过多的人搞砸了!谢谢Janbro。
BoiseBaked

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>

这似乎是按照构建配置更改app.config文件的另一种超级简单的方法。Mike,您是否使用标准的“调试和发布配置”进行了测试?
Boise

0

在对用于开发和构建的配置管理进行了一些研究之后,我决定自己动手制作,并在以下位置的bitbucket上提供了它:https ://bitbucket.org/brightertools/contemplate/wiki/Home

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

希望这可以帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.