对于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文件?
当前回答
我写了一个很好的扩展来自动化app.config转换,就像在Web应用程序项目配置转换中构建的那样
这个扩展的最大优势是,你不需要在所有的构建机器上安装它
其他回答
我创建了Vishal Joshi发布的另一个替代方案,其中将构建动作更改为内容的需求被删除,并实现了对ClickOnce部署的基本支持。我说基本,是因为我没有彻底测试它,但它应该在典型的ClickOnce部署场景中工作。
该解决方案由一个MSBuild项目组成,一旦导入到现有的windows应用程序项目(*.csproj),将构建过程扩展到考虑app.config转换。
你可以在Visual Studio App.config XML Transformation上阅读更详细的解释,MSBuild项目文件可以从GitHub下载。
这是@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>
它还有一个额外的好处,就是比原来的解决方案要短得多。
根据我的经验,我需要使环境特定的东西是像连接字符串、appsettings和通常的smpt设置。配置系统允许在单独的文件中指定这些内容。所以你可以在app.config/web.config中使用这个:
<appSettings configSource="appsettings.config" />
<connectionStrings configSource="connection.config" />
<system.net>
<mailSettings>
<smtp configSource="smtp.config"/>
</mailSettings>
</system.net>
我通常所做的是将这些特定于配置的部分放在单独的文件中,放在名为ConfigFiles的子文件夹中(取决于是在解决方案根目录中还是在项目级别中)。我为每个配置定义一个文件,例如smtp.config.Debug和smtp.config.Release。
然后你可以像这样定义一个预构建事件:
copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config
在团队开发中,您可以通过在约定中包含%COMPUTERNAME%和/或%USERNAME%来进一步调整。
当然,这意味着目标文件(x.config)不应该放在源代码控制中(因为它们是生成的)。你仍然应该将它们添加到项目文件中,并将它们的输出类型属性设置为“始终复制”或“如果更新则复制”。
简单,可扩展,适用于所有类型的Visual Studio项目(控制台,winforms, wpf, web)。
建议的解决方案将不工作时,类库配置文件引用从另一个项目(在我的情况下,它是Azure工作项目库)。它不会将正确转换后的文件从obj文件夹复制到bin\##configuration-name##文件夹。为了使它在最小的变化下工作,你需要将AfterCompile target改为BeforeCompile:
<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
我尝试了几种解决方案,下面是我个人发现的最简单的一个。 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>