C# 为3个不同的环境转换app.config

C# 为3个不同的环境转换app.config,c#,.net,msbuild,slowcheetah,xdt-transform,C#,.net,Msbuild,Slowcheetah,Xdt Transform,我需要能够使用msbuild转换app.config文件。如果文件名为app.DEBUG.config或app.Release.config,我可以对其进行转换,但如果添加名为app.PROD.config的文件,则无法进行转换 如果选择不同的PublishProfile,则使用常规XDT转换msbuild可以识别不同的web.config文件 msbuild path.to.project.csproj Configuration=Release PublishProfile=DEV 显然

我需要能够使用msbuild转换app.config文件。如果文件名为app.DEBUG.config或app.Release.config,我可以对其进行转换,但如果添加名为app.PROD.config的文件,则无法进行转换

如果选择不同的PublishProfile,则使用常规XDT转换msbuild可以识别不同的web.config文件

 msbuild path.to.project.csproj Configuration=Release PublishProfile=DEV
显然app.config不适用于相同的设置。我总是可以为DEV.config设置创建一个特定的构建配置,但是为一个应用程序创建一个单独的构建确认似乎是无用的。要做到这一点,一种很有技巧的方法是在构建后每个环境复制正确的app.config

我曾尝试使用SlowCheetah插件,但这似乎只是转换默认的调试和发布配置文件,这是不合适的,因为我有两个以上的环境。如果我确实使用了此错误,请让我知道应该向msbuild传递什么参数以选择我的app.DEV.config


预期结果是,msbuild将根据名为app.DEV.config的自定义转换或为app.PROD.config自定义的转换转换app.config。我希望有一个参数可以传递给msbuild,该参数允许我使用发行版配置,但每个环境使用不同名称的转换。

这是我在此场景中使用的:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!-- This target will run right before you run your app in Visual Studio -->
  <Target Name="UpdateWebConfigBeforeRun" BeforeTargets="Build">
    <Message Text="Configuration: $(Configuration) update from web.template.$(Configuration).config"/>
    <TransformXml Source="web.template.config"
              Transform="web.template.$(Configuration).config"
              Destination="web.config" />
    </Target>

  <!-- Exclude the config template files from the created package -->
  <Target Name="ExcludeCustomConfigTransformFiles" BeforeTargets="ExcludeFilesFromPackage">
    <ItemGroup>
      <ExcludeFromPackageFiles Include="web.template.config;web.template.*.config"/>
    </ItemGroup>
    <Message Text="ExcludeFromPackageFiles: @(ExcludeFromPackageFiles)" Importance="high"/>
  </Target>
</Project>

在您的场景中,应该可以跨pc工作,而不需要额外的插件等,你需要编辑的内容是
app.
而不是
web.

我认为令人困惑的是,我们有能力进行编译时配置转换,然后进行部署时配置转换

通常,您可以使用编译时配置转换对本地默认配置文件进行更改,以使其适合调试或发布配置(或您定义的任何自定义配置)。对于web.config,工具是内置的。对于app.config,将与web.config相同的功能带到app.config。发布配置的配置转换示例是删除system.web编译上的debug属性

部署时配置转换是在部署到特定环境(例如QA、PROD)时对配置文件的操作。数据库连接字符串需要更改,服务端点需要更改,等等。。。对于web.config,MSDEPLOY是首选的IIS工具。对于app.config,我们似乎需要依赖安装程序技术。有不同的工具,例如

无论如何,我希望这篇关于编译时和部署时配置转换之间区别的简短解释能够帮助解释为什么工具集是碎片化的。要进行更深入的分析,您可以参考我关于这个主题的一篇博文:

如果选择使用WIX工具集生成安装程序,请参阅

App.config转换

要测试转换是否有效,必须使用真实的转换。使用appSettings块插入变换可能是最简单的一种。我使用以下配置文件进行了测试

App.config:


App.Release.config


转换后的配置文件:


使App.config转换生效

让我们看看如何使用控制台应用程序来实现这一点

  • 将App.config和App.Release.config添加到项目中,并用上面给出的内容填充它们
  • 卸载控制台应用程序项目
  • 右键单击项目名称并选择“编辑”
  • 项目文件以XML文件的形式打开,您可以看到其中的内容 它
  • 在关闭第一个属性组的标记之前,添加以下行:

    <ProjectConfigFileName>App.Config</ProjectConfigFileName>
    
    App.Config
    
  • 找到定义App.Config的地方(
    ),并在后面添加以下块 App.Config节点:

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

  • 首先查找
    您可以将app.config转换为与web.config相同的格式。
    使用位于此处的nuget软件包

    还有其他几个Nuget软件包允许您这样做。前几天我用过这个,效果很好


    安装完成后,只需从VS窗口添加转换即可。

    这在今天仍然有效吗?或者vs2015.3正确地处理了这个问题吗?我上周只在vs2015中这样做了,它为转换语法的Merreference工作,对任何感兴趣的人来说:这个答案是从哪里偷来的,对任何想知道的人来说。Dude甚至不能稍微改变措辞。它应该首先在web.template.config上转换发行版,然后再在web.template.config上转换产品。构建文件就是这样做的吗?我必须在项目文件中包含正常的web应用程序导入,并且我必须将
    条件设置为true,然后才能工作
    (请参阅@Nirav Mehta对其他导入的回答)
    <None Include="App.Release.config"> 
        <DependentUpon>App.Config</DependentUpon>
    </None>
    
    <Import Project="$(VSToolsPath)\Web\Microsoft.Web.Publishing.targets" Condition="'$(VSToolsPath)' != ''" />
    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" Condition="false" />
    
    <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
    <Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
      <TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
      <ItemGroup>
        <AppConfigWithTargetPath Remove="app.config" />
        <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
          <TargetPath>$(TargetFileName).config</TargetPath>
        </AppConfigWithTargetPath>
        <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
          <TargetPath>$(TargetName).vshost$(TargetExt).config</TargetPath>
        </AppConfigWithTargetPath>
      </ItemGroup>
    </Target>