对现在似乎到处发布的解决方案稍作改进:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
您可以为每个配置使用单独的配置文件,例如app.Debug.config,app.Release.config然后在项目文件中使用配置变量:
<PropertyGroup> <AppConfig>App.$(Configuration).config</AppConfig> </PropertyGroup>
然后,这将根据您正在构建的配置创建正确的ProjectName.exe.config文件。
我发现的另一个解决方案是不使用转换,而只是有一个单独的配置文件,例如app.Release.config。然后将此行添加到csproj文件中。
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <AppConfig>App.Release.config</AppConfig> </PropertyGroup>
这不仅会生成正确的myprogram.exe.config文件,但如果您在Visual Studio中使用安装和部署项目生成MSI,它将强制部署项目在打包时使用正确的配置文件。
我编写了一个很好的扩展来自动化app.config转换,就像Web应用程序项目中内置的一样 配置转换
此扩展的最大优点是您无需在所有构建计算机上安装它
我创建了另一个替代Vishal Joshi发布的替代方案,其中需要将构建操作更改为 的 内容 强> 已删除,并且还实现了对ClickOnce部署的基本支持。我说基本的,因为我没有彻底测试它,但它应该在典型的ClickOnce部署方案中工作。
该解决方案由单个MSBuild项目组成,该项目一旦导入到现有的Windows应用程序项目(* .csproj),就会扩展构建过程以考虑app.config转换。
你可以在这里阅读更详细的解释 Visual Studio App.config XML转换 和MSBuild项目文件可以 从GitHub下载 。
所以我最终采取了略微不同的方法。我按照Dan的步骤完成了第3步,但添加了另一个文件:App.Base.Config。此文件包含每个生成的App.Config中所需的配置设置。然后我使用BeforeBuild(将Yuri添加到TransformXml中)将当前配置与Base配置转换为App.config。然后,构建过程正常使用转换后的App.config。但是,有一种烦恼是你想要从源代码控制中排除不断变化的App.config,但其他配置文件现在依赖于它。
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="BeforeBuild" Condition="exists('app.$(Configuration).config')"> <TransformXml Source="App.Base.config" Transform="App.$(Configuration).config" Destination="App.config" /> </Target>
从Marketplace中安装Visual Studio中的“配置转换工具”并重新启动VS.您还可以看到app.config的菜单预览转换。
https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform
灵感来自 奥列格 和其他人在这个问题上,我采取了解决方案 https://stackoverflow.com/a/5109530/2286801 进一步实现以下目标。
此解决方案通过在MSBuild进程中首次引用app.config之前执行app.config转换来工作。它使用外部目标文件,以便更轻松地管理多个项目。
与其他解决方案类似的步骤。我引用了相同的内容并将其包含在内,以便完整性和更容易比较。
的 0.在项目中添加一个名为AppConfigTransformation.targets的新文件 强>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- Transform the app config per project configuration.--> <PropertyGroup> <!-- This ensures compatibility across multiple versions of Visual Studio when using a solution file. However, when using MSBuild directly you may need to override this property to 11.0 or 12.0 accordingly as part of the MSBuild script, ie /p:VisualStudioVersion=11.0; See http://blogs.msdn.com/b/webdev/archive/2012/08/22/visual-studio-project-compatability-and-visualstudioversion.aspx --> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> </PropertyGroup> <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets" /> <Target Name="SetTransformAppConfigDestination" BeforeTargets="PrepareForBuild" Condition="exists('app.$(Configuration).config')"> <PropertyGroup> <!-- Force build process to use the transformed configuration file from now on. --> <AppConfig>$(IntermediateOutputPath)$(TargetFileName).config</AppConfig> </PropertyGroup> <Message Text="AppConfig transformation destination: = $(AppConfig)" /> </Target> <!-- Transform the app.config after the prepare for build completes. --> <Target Name="TransformAppConfig" AfterTargets="PrepareForBuild" Condition="exists('app.$(Configuration).config')"> <!-- Generate transformed app config in the intermediate directory --> <TransformXml Source="app.config" Destination="$(AppConfig)" Transform="app.$(Configuration).config" /> </Target> </Project>
的 1.为项目添加每个配置的XML文件。 强> 通常,您将具有调试和发布配置,因此将文件命名为App.Debug.config和App.Release.config。在我的项目中,我为每种环境创建了一个配置,因此您可能想要尝试一下。 的 2.卸载项目并打开.csproj文件进行编辑 强> Visual Studio允许您在编辑器中编辑.csproj - 您只需要先卸载项目。然后右键单击它并选择Edit .csproj。
的 1.为项目添加每个配置的XML文件。 强>
通常,您将具有调试和发布配置,因此将文件命名为App.Debug.config和App.Release.config。在我的项目中,我为每种环境创建了一个配置,因此您可能想要尝试一下。
的 2.卸载项目并打开.csproj文件进行编辑 强>
Visual Studio允许您在编辑器中编辑.csproj - 您只需要先卸载项目。然后右键单击它并选择Edit .csproj。
的 3.将App。*。配置文件绑定到主App.config 强>
找到包含所有App.config和App。*。config引用的项目文件部分,并替换如下。您会注意到我们使用None而不是Content。
<ItemGroup> <None Include="app.config"/> <None Include="app.Production.config"> <DependentUpon>app.config</DependentUpon> </None> <None Include="app.QA.config"> <DependentUpon>app.config</DependentUpon> </None> <None Include="app.Development.config"> <DependentUpon>app.config</DependentUpon> </None> </ItemGroup>
的 4.激活变形魔法 强> 在文件结束之后 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 在决赛之前 </Project>
的 4.激活变形魔法 强>
在文件结束之后
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
在决赛之前
</Project>
插入以下XML:
<Import Project="AppConfigTransformation.targets" />
完成!
当从另一个项目引用具有配置文件的类库时(在我的情况下,它是Azure工作项目库),建议的解决方案将不起作用。它不会从中复制正确的转换文件 obj 文件夹到 bin\##configuration-name## 夹。要使其以最小的更改工作,您需要更改 AfterCompile 目标 BeforeCompile :
obj
bin\##configuration-name##
AfterCompile
BeforeCompile
<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
我尝试了几种解决方案,这是我个人发现的最简单的方法。 担 在评论中指出 原帖 属于 Oleg Sych - 的 谢谢,奥列格! 强>
以下是说明:
通常你会有 Debug 和 Release 配置,因此命名您的文件 App.Debug.config 和 App.Release.config 。在我的项目中,我为每种环境创建了一个配置,因此您可能想要尝试一下。
Debug
Release
App.Debug.config
App.Release.config
Visual Studio允许您编辑 的 的.csproj 强> 编辑器中的文件 - 您只需要先卸载项目。然后右键单击它并选择 的 编辑&lt; ProjectName&gt; .csproj 强> 。
找到包含所有项目的项目文件部分 App.config 和 App.*.config 引用。您会注意到他们的构建操作设置为 None :
App.config
App.*.config
None
<None Include="App.config" /> <None Include="App.Debug.config" /> <None Include="App.Release.config" />
首先,为所有人设置构建操作 Content 。 接下来,全力以赴 配置专用 档 的 依赖的 强> 在主要的 App.config 所以Visual Studio将它们归类为设计器和代码隐藏文件。
Content
将上面的XML替换为下面的XML:
<Content Include="App.config" /> <Content Include="App.Debug.config" > <DependentUpon>App.config</DependentUpon> </Content> <Content Include="App.Release.config" > <DependentUpon>App.config</DependentUpon> </Content>
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="CoreCompile" Condition="exists('app.$(Configuration).config')"> <!-- Generate transformed app config in the intermediate directory --> <TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" /> <!-- Force build process to use the transformed configuration file from now on. --> <ItemGroup> <AppConfigWithTargetPath Remove="app.config" /> <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config"> <TargetPath>$(TargetFileName).config</TargetPath> </AppConfigWithTargetPath> </ItemGroup> </Target>
现在您可以重新加载项目,构建它并享受它 App.config 转换!
的 FYI 强>
确保你的 App.*.config 文件具有正确的设置,如下所示:
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <!--magic transformations here--> </configuration>
我用这个工具解决了这个问题 http://ctt.codeplex.com/ 。我将它与CCNet / nAnt脚本一起用于制作包。
如果您在线使用TFS(云版本)并且想要在项目中转换App.Config,则无需安装任何额外工具即可执行以下操作。 来自VS =&gt;卸载项目=&gt;编辑项目文件=&gt;转到文件底部并添加以下内容:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')"> <TransformXml Source="App.config" Transform="App.$(Configuration).config" Destination="$(OutDir)\$(AssemblyName).dll.config" />
AssemblyFile和Destination适用于本地使用和TFS在线(云)服务器。
根据我的经验,我需要制作特定于环境的东西是连接字符串,appsettings和经常smpt设置。配置系统允许在单独的文件中指定这些内容。所以你可以在app.config / web.config中使用它:
<appSettings configSource="appsettings.config" /> <connectionStrings configSource="connection.config" /> <system.net> <mailSettings> <smtp configSource="smtp.config"/> </mailSettings> </system.net>
我通常做的是将这些特定于配置的部分放在单独的文件中,在名为ConfigFiles的子文件夹中(在解决方案根目录或项目级别,取决于)。我为每个配置定义一个文件,例如smtp.config.Debug和smtp.config.Release。
然后你可以定义一个预构建事件,如下所示:
copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config
在团队开发中,您可以通过在约定中包含%COMPUTERNAME%和/或%USERNAME%来进一步调整此值。
当然,这意味着目标文件(x.config)不应该放在源代码控制中(因为它们是生成的)。您仍应将它们添加到项目文件中,并将其输出类型属性设置为“始终复制”或“如果更新则复制”。
简单,可扩展,适用于所有类型的Visual Studio项目(控制台,winforms,wpf,web)。
现在使用本文中处理的Visual Studio AddIn: SlowCheetah - Web.config转换语法现在针对任何XML配置文件进行了通用化 。
您可以右键单击web.config并单击“添加配置” 转换。“当你这样做时,你会得到一个web.debug.config和一个 web.release.config。如果你愿意,你可以制作一个web.whatever.config 只要名称与配置文件一致。这些文件 只是你想要的改变,而不是你的完整副本 web.config中。 您可能认为您想要使用XSLT转换web.config,但是 虽然他们觉得直觉正确,但实际上非常冗长。 这是两个转换,一个使用XSLT,另一个使用XML Document Transform语法/命名空间。就像所有事情一样 XSLT中有多种方法可以做到这一点,但是你会得到一般的想法。 XSLT 是一种通用的树转换语言,而这种部署 一个针对特定场景的特定子集进行了优化。但是, 很酷的部分是每个XDT转换都是一个.NET插件,所以你可以做 你自己。 <?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/configuration/appSettings"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> <xsl:element name="add"> <xsl:attribute name="key">NewSetting</xsl:attribute> <xsl:attribute name="value">New Setting Value</xsl:attribute> </xsl:element> </xsl:copy> </xsl:template> </xsl:stylesheet> 或者通过部署转换同样的事情: <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <appSettings> <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/> </appSettings> </configuration>
您可以右键单击web.config并单击“添加配置” 转换。“当你这样做时,你会得到一个web.debug.config和一个 web.release.config。如果你愿意,你可以制作一个web.whatever.config 只要名称与配置文件一致。这些文件 只是你想要的改变,而不是你的完整副本 web.config中。
您可能认为您想要使用XSLT转换web.config,但是 虽然他们觉得直觉正确,但实际上非常冗长。
这是两个转换,一个使用XSLT,另一个使用XML Document Transform语法/命名空间。就像所有事情一样 XSLT中有多种方法可以做到这一点,但是你会得到一般的想法。 XSLT 是一种通用的树转换语言,而这种部署 一个针对特定场景的特定子集进行了优化。但是, 很酷的部分是每个XDT转换都是一个.NET插件,所以你可以做 你自己。
<?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/configuration/appSettings"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> <xsl:element name="add"> <xsl:attribute name="key">NewSetting</xsl:attribute> <xsl:attribute name="value">New Setting Value</xsl:attribute> </xsl:element> </xsl:copy> </xsl:template> </xsl:stylesheet>
或者通过部署转换同样的事情:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <appSettings> <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/> </appSettings> </configuration>