对于Visual Studio 2010基于Web的应用程序,我们有配置转换功能,通过它我们可以为不同的环境维护多个配置文件。但同样的功能不适用于Windows服务/WinForms或控制台应用程序的App.Config文件。
这里有一个可用的解决方案:对App.Config应用XDT魔术。
然而,这并不简单,需要一些步骤。是否有更简单的方法来实现同样的app.config文件?
对于Visual Studio 2010基于Web的应用程序,我们有配置转换功能,通过它我们可以为不同的环境维护多个配置文件。但同样的功能不适用于Windows服务/WinForms或控制台应用程序的App.Config文件。
这里有一个可用的解决方案:对App.Config应用XDT魔术。
然而,这并不简单,需要一些步骤。是否有更简单的方法来实现同样的app.config文件?
当前回答
注意:由于声誉,我不能评论bdeem的帖子。我将把我的发现作为答案发表出来。
根据bdeem的帖子,我做了以下(按顺序):
1. 我修改了[项目]。csproj文件。为不同的配置文件添加<Content Include="" />标签到ItemGroup,并使它们依赖于原始配置文件。
注意:使用<None Include="" />对转换无效。
<!-- App.config Settings -->
<!-- Create App.($Configuration).config files here. -->
<Content Include="App.config" />
<Content Include="App.Debug.config">
<DependentUpon>App.config</DependentUpon>
</Content>
<Content Include="App.Release.config">
<DependentUpon>App.config</DependentUpon>
</Content>
2. 在[项目]的底部。csproj文件(在关闭</Project>标记之前),我导入了${MSBuildToolsPath\Microsoft.CSharp。添加UsingTask来转换XML,并添加Target来将转换后的App.config文件复制到输出位置。
注意:Target还将覆盖本地目录中的App.Config,以查看本地工作的即时更改。Target还使用Name="Afterbuild"属性来确保在生成可执行文件之后可以转换配置文件。出于我不理解的原因,当使用WCF端点时,如果我使用Name="CoreCompile",我会得到关于服务属性的警告。Name="Afterbuild"解决了这个问题。
<!-- Task to transform the App.config using the App.($Configuration).config file. -->
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<!-- Only compile the App.config if the App.($Configuration).config file exists. -->
<!-- Make sure to use the AfterBuild name instead of CoreCompile to avoid first time build errors and WCF endpoint errors. -->
<Target Name="AfterBuild" Condition="exists('App.$(Configuration).config')">
<!-- Generate transformed App.config in the intermediate output directory -->
<TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
<!-- Modify the original App.config file with the transformed version. -->
<TransformXml Source="App.config" Destination="App.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>
</Project>
3.回到Visual Studio,重新加载修改过的文件。
4. 手动添加应用。配置文件到项目。这允许它们在原始App.config文件下进行分组。
注:确保App.*.;配置文件具有适当的XML结构。
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="myConn" connectionString=""; Initial Catalog=; User ID=; Password=;" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</connectionStrings>
</configuration>
5. 重建项目。
其他回答
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>
在Visual Studio中从市场安装“配置转换工具”并重新启动VS.你也可以看到app.config的菜单预览转换。
https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform
我写了一个很好的扩展来自动化app.config转换,就像在Web应用程序项目配置转换中构建的那样
这个扩展的最大优势是,你不需要在所有的构建机器上安装它
注意:由于声誉,我不能评论bdeem的帖子。我将把我的发现作为答案发表出来。
根据bdeem的帖子,我做了以下(按顺序):
1. 我修改了[项目]。csproj文件。为不同的配置文件添加<Content Include="" />标签到ItemGroup,并使它们依赖于原始配置文件。
注意:使用<None Include="" />对转换无效。
<!-- App.config Settings -->
<!-- Create App.($Configuration).config files here. -->
<Content Include="App.config" />
<Content Include="App.Debug.config">
<DependentUpon>App.config</DependentUpon>
</Content>
<Content Include="App.Release.config">
<DependentUpon>App.config</DependentUpon>
</Content>
2. 在[项目]的底部。csproj文件(在关闭</Project>标记之前),我导入了${MSBuildToolsPath\Microsoft.CSharp。添加UsingTask来转换XML,并添加Target来将转换后的App.config文件复制到输出位置。
注意:Target还将覆盖本地目录中的App.Config,以查看本地工作的即时更改。Target还使用Name="Afterbuild"属性来确保在生成可执行文件之后可以转换配置文件。出于我不理解的原因,当使用WCF端点时,如果我使用Name="CoreCompile",我会得到关于服务属性的警告。Name="Afterbuild"解决了这个问题。
<!-- Task to transform the App.config using the App.($Configuration).config file. -->
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<!-- Only compile the App.config if the App.($Configuration).config file exists. -->
<!-- Make sure to use the AfterBuild name instead of CoreCompile to avoid first time build errors and WCF endpoint errors. -->
<Target Name="AfterBuild" Condition="exists('App.$(Configuration).config')">
<!-- Generate transformed App.config in the intermediate output directory -->
<TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
<!-- Modify the original App.config file with the transformed version. -->
<TransformXml Source="App.config" Destination="App.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>
</Project>
3.回到Visual Studio,重新加载修改过的文件。
4. 手动添加应用。配置文件到项目。这允许它们在原始App.config文件下进行分组。
注:确保App.*.;配置文件具有适当的XML结构。
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="myConn" connectionString=""; Initial Catalog=; User ID=; Password=;" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</connectionStrings>
</configuration>
5. 重建项目。
这是@bdeem使用Visual Studio 2019年和2022年回答的另一个变体。我的问题是,使用这个解决方案,App.config会被覆盖,因为它在源代码控制中,这不是一个真正的选项。
我的解决方案是将配置文件直接转换到输出目录中。
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
<!-- Generate transformed app config to the output directory -->
<TransformXml Source="App.config" Destination="$(OutDir)\$(TargetFileName).config" Transform="App.$(Configuration).config" />
</Target>
它还有一个额外的好处,就是比原来的解决方案要短得多。