如何为多个构建配置选择不同的 app.config
Posted
技术标签:
【中文标题】如何为多个构建配置选择不同的 app.config【英文标题】:How to select different app.config for several build configurations 【发布时间】:2011-12-26 07:53:04 【问题描述】:我有一个包含 MSTest 集成测试的 dll 类型项目。在我的机器上,测试通过了,我希望在 CI 服务器(我使用 TeamCity)上发生同样的事情。但是测试失败了,因为我需要调整 app.config 中的一些设置。这就是为什么我想有一个单独的第二个 app.config 文件来保存 CI 服务器的设置。
所以我想拥有
/Sln /项目 app.config(我认为这是VS需要的) app.Release.config(这是一个独立的独立配置文件)因此,如果我在 CI 的构建配置中选择发布配置,我想使用 app.Release.config 文件而不是 app.config
问题 对于简单的 .dll 类型的项目,这似乎并不简单。对于 Web 项目,我可以进行 Web 配置转换。我发现了一个如何为 dll 类型项目进行这些转换的 hack,但我不是 hack 的忠实粉丝。
问题 根据 .NET 项目(例如 Debug、Release 等)的构建配置来调整 app.config 文件的标准方法是什么?
【问题讨论】:
【参考方案1】:使用SlowCheetah 插件。有关如何使用 SlowCheetah 的更多选项和详细信息,请继续阅读。
正如您已经注意到的,对于库类型 (.dll) 项目,没有默认且简单的方法可以使用不同的配置文件。原因是目前的想法是:“你不需要”!框架开发人员认为您需要对可执行文件进行配置:无论是控制台、桌面、Web、移动应用程序还是其他东西。如果你开始为 dll 提供配置,你最终可能会得到我可以称之为 config hell 的东西。您可能不再(容易地)理解为什么这个和那个变量有如此奇怪的值,似乎不知从何而来。
“等一下”,- 你可能会说,“但我需要它来进行集成/单元测试,并且它是一个库!”。这是真的,这就是你可以做的(只选择一个,不要混用):
1。 SlowCheetah - 转换当前配置文件
您可以安装 SlowCheetah - 一个 Visual Studio 插件,可以为您执行所有低级 XML 戳(或转换)。它的工作方式,简要说明:
安装 SlowCheetah 并重新启动 Visual Studio(Visual Studio > 工具 > 扩展和更新 ... > 在线 > Visual Studio 库 > 搜索“Slow Cheetah”) 定义您的解决方案配置(Debug 和 Release 默认存在),您可以添加更多(在 Solution Explorer 中右键单击解决方案 > 配置管理器... > 活动解决方案配置 > 新建... 根据需要添加配置文件 右键单击配置文件> 添加转换 这将创建转换文件 - 每个配置一个 转换文件作为注入器/变更器工作,它们在原始配置文件中找到所需的 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 中,您可以拥有类似的东西
3。在 Visual Studio 之外使用脚本文件
每个构建工具(如NAnt、MSBuild)都将提供根据配置转换配置文件的功能。如果您在构建机器上构建解决方案,这很有用,您需要更好地控制您准备发布产品的内容和方式。
例如,您可以使用网络发布 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。 @MassoodKhaari 您需要确保为发布目标调用此任务。当您发布项目时,会调用一个单独的构建目标,默认情况下可能不会调用AfterBuild
目标。在典型的编译过程中,AfterBuild
目标默认被调用。发布案例应该有一个快速修复
使用了第二种方法(有点)。转到项目属性并编辑 BeforeBuild 以将 App.<Target>.config
复制到 项目目录 中的 App.config
上,而不是输出目录。
@oleksii 你是对的。但我仍然找不到我的网络发布过程正在使用的目标(在 Visual Studio 2013 中)。
我使用的是第二种方法,但需要在AfterBuild目标中添加一个条件以确保文件在删除之前确实存在。我有一个 Debug 构建配置,它基本上只使用默认的 App.config 文件,但我没有 App.Debug.config,这意味着构建步骤会失败。我刚刚添加了Condition="Exists('$(ProjectDir)App.$(Configuration).config')"
。【参考方案2】:
您可以尝试以下方法:
-
在解决方案资源管理器中右键单击项目并选择卸载项目。
项目将被卸载。再次右键单击该项目并选择Edit
-
将此行替换为以下内容:
我还没有对app.config
文件尝试过这种方法,但它与 Visual Studio 项目的其他项目配合得很好。您几乎可以以任何您喜欢的方式自定义构建过程。无论如何,让我知道结果。
【讨论】:
Tnx 的答案,但这不适用于 app.config。 VS 需要一个强制的app.config
,如果我使用 VS build 或 Teamcity VS sln build runner,则不会应用发布配置。
这里解释了如何做到这一点:Enable app.debug.config app.release.config
为什么这个答案有这么多赞成票?我试过了,它不起作用。事实上,在调试和发布模式下都没有 App.config 文件,因此输出文件夹中也没有相应的文件。文件 App.Debug.config 和 App.Release.config 对 Visual Studio 没有任何意义。
它不起作用:.csproj 无法打开,错误消息“目标元素之外的元素必须具有:包含、更新或删除”【参考方案3】:
使用与 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】:您应该考虑ConfigGen。它是为此目的而开发的。它基于模板文件和设置文件为每台部署机器生成一个配置文件。我知道这并不能具体回答您的问题,但它可能会很好地回答您的问题。
因此,除了 Debug、Release 等,您可能有 Test、UAT、Production 等。您还可以为每台开发机器设置不同的设置,以便您可以生成特定于您的开发机器的配置并更改它而不影响任何别人的部署。
一个使用示例可能是...
<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>
从第二个命令开始,您的开发机器上使用的本地 App.config 将被本地 (-l) 开关和文件名 (-n) 开关指定的生成配置替换。
【讨论】:
Tnx 的答案,这看起来不错。但也有一些缺点,它只显示 75 次下载(因此它不成熟)并且它仅适用于 .xls 或 .xlsx。我真的不想依赖另一种自定义文档格式来进行简单的操作。我正在寻找一种更标准的方法...... 公平点,虽然它说 CodePlex 上有 194 次下载,但 xls 是一个电子表格,几乎不是自定义格式,而且我知道三个主要的投资银行已经批准使用它,所以如果它足够好为他们...此外,当前请求的功能之一是使用 xml 进行设置。它几乎准备好了,但无论如何我更喜欢电子表格方法。在表格视图中查看每个环境的每个设置要容易得多 我们现在正处于测试 configGen 版本的最后阶段,该版本可用于生成纯文本文件,而不仅仅是 xml。所以如果你想生成环境特定的 css、sql、javascript 等,请留意 configGen 站点 感谢 Daniel 的解决方案,这正是我想要的。我会试一试的。【参考方案5】:我听说过关于 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,您是否使用标准的调试和发布配置进行了测试?【参考方案6】:我正在使用XmlPreprocess tool 进行配置文件操作。它为多个环境(或在您的情况下为多个构建目标)使用一个映射文件。您可以通过 Excel 编辑映射文件。它非常易于使用。
【讨论】:
【参考方案7】:VisualStudio Gallery 中的 SlowCheetah 和 FastKoala 似乎是解决这个问题的好工具。
但是,如果您想避免插件或在您的构建/集成过程中更广泛地使用它们实施的原则,那么将其添加到您的 msbuild *proj 文件是一种速记修复。
注意:这或多或少是对@oleksii 答案中第二条的修改。
这适用于 .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>
【讨论】:
我刚刚在 Visual Studio 2017 中尝试过,但它不起作用。射击。我真的希望它能起作用,因为它看起来是最容易实现的。 示例中未定义 TransformXml 任务。我正在添加一个条目。您可以在 mycustom.targets 文件中定义它,该文件包含在解决方案中的所有启动项目中。 @GregBurghardt,你现在要试试吗? 我可以试一试。我为 Visual Studio 安装了 Config Transform 插件,效果非常好。我实际上想知道该插件是否基本上可以完成您的回答。 好的,告诉我进展如何。【参考方案8】:我已经用我在这里找到的解决方案解决了这个问题: http://www.blackwasp.co.uk/SwitchConfig.aspx
简而言之,他们所说的是: “通过添加构建后事件。[...] 我们需要添加以下内容:
if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy
【讨论】:
迄今为止最简单的方法来完成本应是一个非常简单且必不可少的功能,但被过度思考的人搞砸了!谢谢 Janbro。【参考方案9】:看看 XDT (web.config) 转换引擎是否可以帮助您。目前它仅原生支持 Web 项目,但从技术上讲,没有什么能阻止您在其他应用程序类型中使用它。有很多关于如何通过手动编辑项目文件来使用 XDT 的指南,但我发现了一个很好用的插件:https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859
插件只是帮助设置配置,不需要构建,解决方案可以在其他机器或构建服务器上构建,而不需要插件或任何其他工具。
【讨论】:
这应该是现在的答案。刚刚在 VS 2017 上试用过,它就像一个魅力。您不需要发布项目。只需构建它。非常适合我们的测试项目,用于我们的持续集成构建,因此我们可以在无头模式下运行 Selenium 测试,但在浏览器打开的情况下在本地运行。如果可以的话,+1,000,000。【参考方案10】:在对管理配置以进行开发和构建等进行了一些研究之后,我决定推出自己的产品,我已将其发布在 bitbucket 上:https://bitbucket.org/brightertools/contemplate/wiki/Home
这个适用于多种环境的多个配置文件,它是一个基本的配置条目替换工具,适用于任何基于文本的文件格式。
希望这会有所帮助。
【讨论】:
以上是关于如何为多个构建配置选择不同的 app.config的主要内容,如果未能解决你的问题,请参考以下文章