visual-studio 不是 Visual Studio 中的 Web 项目的项目的 App.Config 转换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3004210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 12:05:37  来源:igfitidea点击:

App.Config Transformation for projects which are not Web Projects in Visual Studio?

visual-studio.net-4.0app-configslowcheetahweb-config-transform

提问by Amitabh

For Visual Studio 2010 Web based application we have Config Transformation features by which we can maintain multiple configuration files for different environments. But the same feature is not available for App.Config files for Windows Services/WinForms or Console Application.

对于基于 Visual Studio 2010 Web 的应用程序,我们具有配置转换功能,我们可以通过它为不同环境维护多个配置文件。但同样的功能不适用于 Windows 服务/WinForms 或控制台应用程序的 App.Config 文件。

There is a workaround available as suggested here: Applying XDT magic to App.Config.

此处建议了一种解决方法:将 XDT 魔法应用到 App.Config

However it is not straightforward and requires a number of steps. Is there an easier way to achieve the same for app.config files?

然而,这并不简单,需要许多步骤。有没有更简单的方法来为 app.config 文件实现相同的目标?

采纳答案by Scott Hanselman

This works now with the Visual Studio AddIn treated in this article: SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file.

这现在适用于本文中处理的 Visual Studio插件SlowCheetah - Web.config 转换语法现在适用于任何 XML 配置文件

You can right-click on your web.config and click "Add Config Transforms." When you do this, you'll get a web.debug.config and a web.release.config. You can make a web.whatever.config if you like, as long as the name lines up with a configuration profile. These files are just the changes you want made, not a complete copy of your web.config.

You might think you'd want to use XSLT to transform a web.config, but while they feels intuitively right it's actually very verbose.

Here's two transforms, one using XSLT and the same one using the XML Document Transform syntax/namespace. As with all things there's multiple ways in XSLT to do this, but you get the general idea. XSLT is a generalized tree transformation language, while this deployment one is optimized for a specific subset of common scenarios. But, the cool part is that each XDT transform is a .NET plugin, so you can make your own.

<?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>

Or the same thing via the deployment transform:

<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 文档转换语法/命名空间。与所有事情一样,在 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>

回答by Dan Abramov

I tried several solutions and here is the simplest I personally found.
Danpointed out in the comments that the original postbelongs to Oleg Sychthanks, Oleg!

我尝试了几种解决方案,这是我个人发现的最简单的解决方案。
Dan在评论中指出原始帖子属于Oleg Sych谢谢,Oleg!

Here are the instructions:

以下是说明:

1. Add an XML file for each configuration to the project.

1. 为每个配置添加一个 XML 文件到项目中。

Typically you will have Debugand Releaseconfigurations so name your files App.Debug.configand App.Release.config. In my project, I created a configuration for each kind of environment, so you might want to experiment with that.

通常,您将拥有DebugRelease配置,因此命名您的文件App.Debug.configApp.Release.config. 在我的项目中,我为每种环境创建了一个配置,因此您可能想对此进行试验。

2. Unload project and open .csproj file for editing

2. 卸载工程并打开.csproj 文件进行编辑

Visual Studio allows you to edit .csprojfiles right in the editor—you just need to unload the project first. Then right-click on it and select Edit <ProjectName>.csproj.

Visual Studio 允许您直接在编辑器中编辑.csproj文件——您只需要先卸载项目。然后右键单击它并选择Edit <ProjectName>.csproj

3. Bind App.*.config files to main App.config

3. 将 App.*.config 文件绑定到主 App.config

Find the project file section that contains all App.configand App.*.configreferences. You'll notice their build actions are set to None:

找到包含所有App.configApp.*.config引用的项目文件部分。您会注意到他们的构建操作设置为None

<None Include="App.config" />
<None Include="App.Debug.config" />
<None Include="App.Release.config" />

First, set build action for all of them to Content.
Next, make all configuration-specificfiles dependanton the main App.configso Visual Studio groups them like it does designer and code-behind files.

首先,将所有它们的构建操作设置为Content.
接下来,使所有特定配置的文件依赖于主文件,App.config以便 Visual Studio 将它们分组,就像对设计器和代码隐藏文件进行分组一样。

Replace XML above with the one below:

用下面的替换上面的 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>

4. Activate transformations magic(only necessary for Visual Studio versions pre VS2017)

4. 激活转换魔法(仅适用于VS2017之前的 Visual Studio 版本)

In the end of file after

在文件末尾之后

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

and before final

在决赛之前

</Project>

insert the following XML:

插入以下 XML:

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

Now you can reload the project, build it and enjoy App.configtransformations!

现在您可以重新加载项目,构建它并享受App.config转换!

FYI

供参考

Make sure that your App.*.configfiles have the right setup like this:

确保您的App.*.config文件具有如下正确设置:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>

回答by Alec

Another solution I've found is NOT to use the transformations but just have a separate config file, e.g. app.Release.config. Then add this line to your csproj file.

我发现的另一个解决方案是不使用转换,而只有一个单独的配置文件,例如 app.Release.config。然后将此行添加到您的 csproj 文件中。

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <AppConfig>App.Release.config</AppConfig>
  </PropertyGroup>

This will not only generate the right myprogram.exe.config file but if you're using Setup and Deployment Project in Visual Studio to generate MSI, it'll force the deployment project to use the correct config file when packaging.

这不仅会生成正确的 myprogram.exe.config 文件,而且如果您在 Visual Studio 中使用安装和部署项目来生成 MSI,它将强制部署项目在打包时使用正确的配置文件。

回答by jeroenh

In my experience, the things I need to make environment-specific are things like connection strings, appsettings and often smpt settings. The config system allows to specify these things in separate files. So you can use this in your app.config/web.config:

根据我的经验,我需要使环境特定于连接字符串、appsettings 和通常的 smpt 设置之类的东西。配置系统允许在单独的文件中指定这些内容。所以你可以在你的 app.config/web.config 中使用它:

 <appSettings configSource="appsettings.config" />
 <connectionStrings configSource="connection.config" />
 <system.net>
    <mailSettings>
       <smtp configSource="smtp.config"/>
    </mailSettings>
 </system.net>

What I typically do is to put these config-specific sections in separate files, in a subfolder called ConfigFiles (either in the solution root or at the project level, depends). I define a file per configuration, e.g. smtp.config.Debug and smtp.config.Release.

我通常做的是将这些特定于配置的部分放在单独的文件中,放在名为 ConfigFiles 的子文件夹中(在解决方案根目录或项目级别,取决于)。我为每个配置定义了一个文件,例如 smtp.config.Debug 和 smtp.config.Release。

Then you can define a pre-build event like so:

然后你可以像这样定义一个预构建事件:

copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config

In team development, you can tweak this further by including the %COMPUTERNAME% and/or %USERNAME% in the convention.

在团队开发中,您可以通过在约定中包含 %COMPUTERNAME% 和/或 %USERNAME% 来进一步调整。

Of course, this implies that the target files (x.config) should NOT be put in source control (since they are generated). You should still add them to the project file and set their output type property to 'copy always' or 'copy if newer' though.

当然,这意味着目标文件 (x.config) 不应置于源代码管理中(因为它们是生成的)。您仍然应该将它们添加到项目文件中,并将它们的输出类型属性设置为“始终复制”或“如果更新则复制”。

Simple, extensible, and it works for all types of Visual Studio projects (console, winforms, wpf, web).

简单、可扩展,适用于所有类型的 Visual Studio 项目(控制台、winforms、wpf、web)。

回答by bdeem

Inspired by Olegand others in this question, I took the solution https://stackoverflow.com/a/5109530/2286801a step further to enable the following.

受到Oleg和其他人在这个问题的启发,我采取了解决方案https://stackoverflow.com/a/5109530/2286801进一步启用以下功能。

  • Works with ClickOnce
  • Works with Setup and Deployment projects in VS 2010
  • Works with VS2010, 2013, 2015 (didn't test 2012 although should work as well).
  • Works with Team Build. (You must install either A) Visual Studio or B) Microsoft.Web.Publishing.targets and Microsoft.Web.Publishing.Tasks.dll)
  • 与 ClickOnce 一起使用
  • 适用于 VS 2010 中的安装和部署项目
  • 适用于 VS2010、2013、2015(没有测试 2012 虽然应该也适用)。
  • 与团队构建一起使用。(您必须安装 A)Visual Studio 或 B)Microsoft.Web.Publishing.targets 和 Microsoft.Web.Publishing.Tasks.dll)

This solution works by performing the app.config transformation before the app.config is referenced for the first time in the MSBuild process. It uses an external targets file for easier management across multiple projects.

此解决方案的工作原理是在 MSBuild 过程中第一次引用 app.config 之前执行 app.config 转换。它使用外部目标文件来更轻松地跨多个项目进行管理。

Instructions:

指示:

Similar steps to the other solution. I've quoted what remains the same and included it for completeness and easier comparison.

与其他解决方案类似的步骤。我引用了保持不变的内容并将其包含在内,以保持完整性和更容易比较。

0. Add a new file to your project called AppConfigTransformation.targets

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. Add an XML file for each configuration to the project.

Typically you will have Debug and Release configurations so name your files App.Debug.config and App.Release.config. In my project, I created a configuration for each kind of enironment so you might want to experiment with that.

2. Unload project and open .csproj file for editing

Visual Studio allows you to edit .csproj right in the editor—you just need to unload the project first. Then right-click on it and select Edit .csproj.

1. 为每个配置添加一个 XML 文件到项目中。

通常,您将拥有 Debug 和 Release 配置,因此将您的文件命名为 App.Debug.config 和 App.Release.config。在我的项目中,我为每种环境创建了一个配置,因此您可能想对此进行试验。

2. 卸载工程并打开.csproj 文件进行编辑

Visual Studio 允许您直接在编辑器中编辑 .csproj — 您只需要先卸载项目。然后右键单击它并选择编辑 .csproj。

3. Bind App.*.config files to main App.config

3. 将 App.*.config 文件绑定到主 App.config

Find the project file section that contains all App.config and App.*.config references and replace as follows. You'll notice we use None instead of Content.

找到包含所有 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. Activate transformations magic

In the end of file after

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

and before final

</Project>

4.激活变身魔法

在文件末尾之后

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

在决赛之前

</Project>

insert the following XML:

插入以下 XML:

<Import Project="AppConfigTransformation.targets" />

Done!

完毕!

回答by Tevin

You can use a separate config file per configuration, e.g. app.Debug.config, app.Release.config and then use the configuration variable in your project file:

您可以为每个配置使用单独的配置文件,例如 app.Debug.config、app.Release.config,然后在您的项目文件中使用配置变量:

<PropertyGroup>
    <AppConfig>App.$(Configuration).config</AppConfig>
</PropertyGroup>

This will then create the correct ProjectName.exe.config file depending on the configuration you are building in.

然后,这将根据您正在构建的配置创建正确的 ProjectName.exe.config 文件。

回答by Golan Avraham

I wrote nice extension to automate app.config transformation like the one built in Web Application Project Configuration Transform

我写了一个很好的扩展来自动化 app.config 转换,就像在 Web 应用程序项目配置转换中构建的那样

The biggest advantage of this extension is that you don't need to install it on all build machines

这个扩展的最大优点是你不需要在所有构建机器上安装它

回答by Agnel Amodia

Install "Configuration Transform Tool" in Visual Studio from Marketplace and restart VS. You will be able to see menu preview transform for app.config as well.

从 Marketplace 在 Visual Studio 中安装“配置转换工具”并重新启动 VS。您还可以看到 app.config 的菜单预览转换。

https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform

https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform

回答by Waggles

So I ended up taking a slightly different approach. I followed Dan's steps through step 3, but added another file: App.Base.Config. This file contains the configuration settings you want in every generated App.Config. Then I use BeforeBuild (with Yuri's addition to TransformXml) to transform the current configuration with the Base config into the App.config. The build process then uses the transformed App.config as normal. However, one annoyance is you kind of want to exclude the ever-changing App.config from source control afterwards, but the other config files are now dependent upon it.

所以我最终采取了一种稍微不同的方法。我按照 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>

回答by Yuri Makassiouk

Just a little improvement to the solution that seems to be posted everywhere now:

只是对现在似乎到处张贴的解决方案的一点改进:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • that is, unless you are planning to stay with your current VS version forever
  • 也就是说,除非您打算永远使用当前的 VS 版本