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

这里有一个可用的解决方案:对App.Config应用XDT魔术。

然而,这并不简单,需要一些步骤。是否有更简单的方法来实现同样的app.config文件?


当前回答

这现在可以与本文中处理的Visual Studio AddIn一起工作: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>

其他回答

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

以下是使用说明:

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

通常你会有调试和发布配置,所以把你的文件命名为App.Debug.config和App.Release.config。在我的项目中,我为每种环境创建了一个配置,所以您可能想尝试一下。

2. 卸载项目并打开.csproj文件进行编辑

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

3.绑定程序。*。配置文件到主App.config

找到包含所有App.config和App.*的项目文件部分。配置引用。你会注意到它们的构建动作被设置为None,这是可以的:

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

接下来,让所有特定于配置的文件都依赖于主App.config,这样Visual Studio就可以像对设计器和代码隐藏文件一样对它们进行分组。

将上面的XML替换为下面的XML:

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

4. 激活转换魔法(对于VS2019等Visual Studio版本仍然是必要的)

在文件结束后

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

在期末考试之前

</Project>

插入以下XML——请注意,要进行正确的转换需要两个步骤:

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="BeforeBuild" Condition="Exists('App.$(Configuration).config')">
    <!-- Generate transformed app config and replace it: will get the <runtime> node and assembly bindings properly populated -->
    <TransformXml Source="App.config" Destination="App.config" Transform="App.$(Configuration).config" />
  </Target>
  <Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
    <!-- Generate transformed app config in the intermediate directory: this will transform sections such as appSettings -->
    <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.*。配置文件有如下正确的设置:

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

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

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

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

使用ClickOnce 在VS 2010中使用安装和部署项目 适用于VS2010, 2013, 2015(没有测试2012,尽管应该工作)。 与团队建设合作。(您必须安装A) Visual Studio或B) Microsoft.Web.Publishing.targets和Microsoft.Web.Publishing.Tasks.dll)

这个解决方案的工作原理是在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。

3.绑定程序。*。配置文件到主App.config

找到包含所有App.config和App.*的项目文件部分。配置引用和替换如下所示。您将注意到我们使用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. 激活转换魔法 在文件结束后 <进口项目= " $ (MSBuildToolsPath) \ Microsoft.CSharp。目标" / > 在期末考试之前 > < /项目

插入以下XML文件:

<Import Project="AppConfigTransformation.targets" />

完成了!

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

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

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

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.

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