App.Config转换为Visual Studio中不是Web项目的项目?

Ami*_*abh 528 app-config .net-4.0 visual-studio web-config-transform slowcheetah

对于Visual Studio 2010基于Web的应用程序,我们具有Config Transformation功能,通过该功能,我们可以为不同的环境维护多个配置文件.但是,对于Windows Services/WinForms或控制台应用程序,App.Config文件无法使用相同的功能.

这里提供了一种解决方法:将XDT魔术应用于App.Config.

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

Dan*_*mov 548

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

以下是说明:

1.为项目添加每个配置的XML文件.

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

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

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

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

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

<None Include="App.config" />
<None Include="App.Debug.config" />
<None Include="App.Release.config" />
Run Code Online (Sandbox Code Playgroud)

首先,为所有人设置构建操作Content.
接下来,使所有特定配置的文件都依赖于主要文件,App.config因此Visual Studio将它们分组为设计器和代码隐藏文件.

将上面的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>
Run Code Online (Sandbox Code Playgroud)

4.激活变形魔法

在文件结束之后

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Run Code Online (Sandbox Code Playgroud)

在决赛之前

</Project>
Run Code Online (Sandbox Code Playgroud)

插入以下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>
Run Code Online (Sandbox Code Playgroud)

现在您可以重新加载项目,构建它并享受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>
Run Code Online (Sandbox Code Playgroud)

  • 您可以用`v $(VisualStudioVersion)`替换`v10.0`以确保您的项目适用于所有更高版本的VS. (24认同)
  • 我有一个错误MSBuild错误MSB3021:无法复制文件.在构建期间找不到文件'obj\Release\ConsoleApp.exe'.所以我改变了一点解决方案来重用目标<Target Name ="AfterBuild">部分,而不是在解决方案中创建一个新的类似 (12认同)
  • 这种方法的一个问题是,当您查看项目属性中的"发布"选项卡,然后单击"应用程序文件"按钮时......您会注意到app.config,app.Debug.config, app.Release.config被强制部署为Publish过程的一部分.当然,您也可以获得正确的MyApp.exe.config文件,但我不希望部署额外的行李.需要有一种方法可以将项目中的app.*.config文件保留为<None>而不是<Content>. (8认同)
  • 这个问题遗漏了一些问题,原来是奥列格·赛奇(Oleg Sych)的答案留下了一个关键部分.如果在你的个人应用程序.(env).configs中,你不要列出'<configuration xmlns:xdt ="http://schemas.microsoft.com/XML-Document-Transform">'和类似<appSettings xdt:Transform = "替换">或在设置行上执行类似操作的属性,它将无法正常工作.最后一点信息是关键,一旦我添加它,它就开始工作了. (6认同)
  • 非常感谢!请注意,如果在编辑csproj后将新的.config文件添加到项目中,它们将显示在App.config下.我在编辑csproj之前添加了一个,最后有两个链接,一个分组和一个独奏. (4认同)
  • 在Tar​​get名称中,AfterCompile对我不起作用,AfterBuild没有. (4认同)
  • 这应该仍然是正确的答案,因为前面提到的插件"SlowCheetah"似乎是不可能的. (2认同)
  • 谢谢,这是要走的路.我一直在尝试在我们的团队中使用SlowCheetah,但大部分时间都是不可行的. (2认同)
  • 我意识到这是五年之后但这似乎仍然是@ ThibaultD的最佳解决方案.的'v $(VisualStudioVersion)'建议,并且没有将`<None />`标签改为`<Content /> (2认同)
  • 我没有在 VS 的早期版本中对此进行过测试,但在 2019 年,我不得不将 `&lt;UsingTask&gt;` 和 `&lt;Target&gt;` 位*放在*现有的 CSharp 目标之前。这是针对 WPF 应用程序的,但它无法编译项目,无法识别大部分代码,也无法识别解决方案中对其他项目的任何项目引用。 (2认同)
  • 另一条评论是,这在 Azure Pipelines 中效果不佳,我最后所做的是使用 FileTransform 任务,在构建解决方案之前应用相同的转换,并从所有 csprojs 中禁用它。在某种程度上,在 CI 时进行是有意义的,并且对于构建过程来说也更加透明。 (2认同)
  • ...在某种程度上,在 CI 时执行是有意义的,因为它本身不是编译,它对于构建过程也更加透明,而且 TransformXml 调用有时不会在本地环境中编译(可能是 VS 版本混合) )。 (2认同)
  • 在 VS19 上,不要忘记更改第 4 步。`&lt;目标名称=“CoreCompile”`至“&lt;目标名称=“AfterCompile””。否则,它将引发构建错误:“无法复制文件“obj\Debug\*.exe”,因为找不到它”。 (2认同)

Sco*_*man 407

现在可以使用本文中处理的Visual Studio AddIn:SlowCheetah - 现在为任何XML配置文件推广的Web.config转换语法.

您可以右键单击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>
Run Code Online (Sandbox Code Playgroud)

或者通过部署转换同样的事情:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
   <appSettings>
      <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/>
   </appSettings>
</configuration>
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,SlowCheetah是一个很棒的扩展,现在在VS 2014之后将不再支持.根据作者,Sayed Ibrahim Hashimi,http://sedodream.com/2014/08/11/SlowCheetahIsGoingIntoMaintenanceMode.aspx. (10认同)
  • @andrewb,我读到[这里](https://github.com/sayedihashimi/slow-cheetah/issues/158); 然而,那是一年前的事.在重新访问该主题并阅读评论后,看起来有人提供了一个适用于VS2015的版本[这里](https://visualstudiogallery.msdn.microsoft.com/05bb50e3-c971-4613-9379-acae2cfe6f9e). (5认同)
  • 与 Visual Studio 2017 和 Visual Studio 2019 完美配合 (2认同)

小智 129

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

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

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

  • MSBuild的无数奇迹.现在我想知道还有什么是可能的.顺便说一句.这也适用于直接来自VS的clickonce部署(与较高投票的答案形成对比). (5认同)
  • 如果配置包含许多所有构建的SAME条目,则更改可能变得繁重且容易出错.现在处理一个问题,其中一个环境的.config错过了一个更改,当然这是生产. (4认同)

jer*_*enh 33

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

 <appSettings configSource="appsettings.config" />
 <connectionStrings configSource="connection.config" />
 <system.net>
    <mailSettings>
       <smtp configSource="smtp.config"/>
    </mailSettings>
 </system.net>
Run Code Online (Sandbox Code Playgroud)

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

然后你可以定义一个预构建事件,如下所示:

copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config
Run Code Online (Sandbox Code Playgroud)

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

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

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


bde*_*eem 29

Oleg和其他人在这个问题的启发,我进一步采用了解决方案/sf/answers/357667131/以启用以下功能.

  • 适用于ClickOnce
  • 适用于VS 2010中的安装和部署项目
  • 与VS2010,2013年,2015年一起使用(虽然应该也能正常运行但未测试2012年).
  • 与Team Build一起使用.(您必须安装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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

4.激活变形魔法

在文件结束之后

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Run Code Online (Sandbox Code Playgroud)

在决赛之前

</Project>
Run Code Online (Sandbox Code Playgroud)

插入以下XML:

<Import Project="AppConfigTransformation.targets" />
Run Code Online (Sandbox Code Playgroud)

完成!


Tev*_*vin 27

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

<PropertyGroup>
    <AppConfig>App.$(Configuration).config</AppConfig>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

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


Gol*_*ham 14

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

此扩展的最大优点是您无需在所有构建计算机上安装它


Agn*_*dia 6

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

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


Yur*_*ouk 5

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

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
Run Code Online (Sandbox Code Playgroud)
  • 也就是说,除非您打算永远使用当前的 VS 版本

  • 直接使用 MSBuild 时似乎没有设置“$(VisualStudioVersion)”。 (4认同)