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

对于基于Visual Studio 2010 Web的应用程序,我们拥有configuration转换function,通过这些function我们可以为不同的环境维护多个configuration文件。 但是,对于Windows服务/ WinForms或控制台应用程序,App.Config文件不具有相同的function。

有一个解决方法可用这里build议: 应用XDT魔术App.Config 。

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

这适用于本文处理的Visual Studio AddIn: SlowCheetah – Web.config转换语法现在已经推广到任何XMLconfiguration文件 。

您可以右键单击您的web.config并单击“添加configuration转换”。 当你这样做,你会得到一个web.debug.config和一个web.release.config。 如果你喜欢,你可以创build一个web.whatever.config,只要名字与configuration文件一致。 这些文件只是你想做的改变,而不是web.config的完整副本。

你可能会认为你想使用XSLT来转换一个web.config,但是当他们觉得直觉的时候,它实际上是非常冗长的。

这里有两个转换,一个使用XSLT,另一个使用XML文档转换语法/命名空间。 与所有的事情一样,XSLT有多种方式来完成这个任务,但是你得到了一般的想法。 XSLT是一种广义的树转换语言,而这个部署是针对特定的常见场景子集进行优化的。 但是,最酷的部分是每个XDT转换都是一个.NET插件,所以你可以自己创build。

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

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

 <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <appSettings> <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/> </appSettings> </configuration> 

我尝试了几个解决scheme,这是我个人发现的最简单的方法。
丹在评论中指出,原来的职位属于奥列格Sych – 谢谢,奥列格!

这里是说明:

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

通常你会有DebugReleaseconfiguration,所以命名你的文件App.Debug.configApp.Release.config 。 在我的项目中,我为每种环境创build了一个configuration,所以您可能想要尝试一下。

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

Visual Studio允许你在编辑器中编辑.csproj文件 – 你只需要先卸载项目。 然后右键单击它并select编辑<ProjectName> .csproj

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

find包含所有App.configApp.*.config参考的项目文件部分。 您会注意到他们的构build操作被设置为None

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

首先,将所有Content构build操作设置为“ Content
接下来,使所有configuration特定的文件依赖于主App.config以便Visual Studio将它们分组,如同devise器和代码隐藏文件一样。

将上面的XMLreplace为下面的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> 

4.激活变换魔法

在文件结尾之后

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

并在决赛之前

 </Project> 

插入以下XML:

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="AfterCompile" 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> 

现在你可以重新加载项目,build立它,并享受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> 

我发现另一个解决scheme是不使用转换,但只有一个单独的configuration文件,例如app.Release.config。 然后将此行添加到您的csproj文件。

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

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

根据我的经验,我需要做的环境特定的东西,如连接string,appsettings和经常smpt设置。 configuration系统允许在单独的文件中指定这些东西。 所以你可以在你的app.config / web.config中使用它:

  <appSettings configSource="appsettings.config" /> <connectionStrings configSource="connection.config" /> <system.net> <mailSettings> <smtp configSource="smtp.config"/> </mailSettings> </system.net> 

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

然后你可以像这样定义一个预生成事件:

 copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config 

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

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

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

您可以使用每个configuration的单独configuration文件,例如app.Debug.config,app.Release.config,然后在您的项目文件中使用configurationvariables:

 <PropertyGroup> <AppConfig>App.$(Configuration).config</AppConfig> </PropertyGroup> 

这将根据您正在构build的configuration创build正确的ProjectName.exe.config文件。

受Oleg和其他人的启发,我采取了解决schemehttps://stackoverflow.com/a/5109530/2286801进一步启用以下内容。

  • 适用于ClickOnce
  • 在VS 2010中使用安装和部署项目
  • 适用于VS2010,2013,2015(没有testing2012年,但应该可以)。
  • 与团队build设一起工作。 (您必须安装A)Visual Studio或B)Microsoft.Web.Publishing.targets和Microsoft.Web.Publishing.Tasks.dll)

此解决scheme通过在MS.Build进程中首次引用app.config之前执行app.config转换工作。 它使用外部目标文件,以便在多个项目中轻松进行pipe理。

说明:

类似的步骤到另一个解决scheme。 我已经引用了相同的内容,并将其纳入了完整性和易于比较的范围。

将一个新文件添加到名为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.将每个configuration的XML文件添加到项目中。

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

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

Visual Studio允许你在编辑器中编辑.csproj,你只需要先卸载项目。 然后右键单击它并select编辑.csproj。

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

find包含所有App.config和App。*。config参考的项目文件部分,并按如下所示进行replace。 你会注意到我们使用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.激活变换魔法

在文件结尾之后

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

并在决赛之前

 </Project> 

插入以下XML:

 <Import Project="AppConfigTransformation.targets" /> 

完成!

我写了很好的扩展来自动化app.config转换,如Web应用程序项目configuration转换中构build的转换

这个扩展的最大优点是你不需要在所有的构build机器上安装它

我遇到以下文章看起来更简单,但我没有尝试过自己。

http://fknut.blogspot.com/2009/11/appconfig-transformation-with-new.html

此外,MS Connect上还有一项function请求,可能值得投票,因此在下一个SP或版本中包含全部function。

https://connect.microsoft.com/VisualStudio/feedback/details/564414

我用这个工具http://ctt.codeplex.com/解决了这个问题。; 我使用CCNet / nAnt脚本来制作软件包。

现在似乎到处都可以发布的解决scheme稍微改进一点:

 <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> 
  • 也就是说,除非你打算永远保留你当前的VS版本

我已经创build了Vishal Joshi发布的另一个替代scheme,其中将构build操作更改为“ 内容”的要求被删除,并且还实施了对ClickOnce部署的基本支持。 我说基本的,因为我没有彻底testing它,但它应该在典型的ClickOnce部署scheme中工作。

该解决scheme包含一个单一的MSBuild项目,一旦导入到现有的Windows应用程序项目(* .csproj)扩展了构build过程,以考虑app.config转换。

您可以在Visual Studio App.config XML Transformation中阅读更详细的说明,并可以从GitHub下载 MSBuild项目文件。

所以我最终采取了一个稍微不同的方法。 我遵循丹的步骤3,但添加了另一个文件:App.Base.Config。 该文件包含您在每个生成的App.Config中所需的configuration设置。 然后,我使用BeforeBuild(带有Yuri除了TransformXml之外)将当前configuration与Baseconfiguration转换为App.config。 生成过程然后正常使用转换后的App.config。 然而,有一种烦恼是你想从源代码pipe理中排除不断变化的App.config,但其他configuration文件现在依赖于它。

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

如果您在线使用TFS(云版本)并且想要在项目中转换App.Config,则可以在不安装任何额外工具的情况下执行以下操作。 从VS =>卸载项目=>编辑项目文件=>转到文件的底部,并添加以下内容:

 <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')"> <TransformXml Source="App.config" Transform="App.$(Configuration).config" Destination="$(OutDir)\$(AssemblyName).dll.config" /> 

AssemblyFile和Destination适用于本地使用和TFS在线(云)服务器。

当一个带有configuration文件的类库被另一个项目引用时(在我的情况下,它是Azure工作者项目库),build议的解决scheme将不起作用。 它不会将正确的转换后的文件从obj文件夹复制到bin\##configuration-name##文件夹中。 要使其以最小的更改工作,您需要将AfterCompile目标更改为BeforeCompile

 <Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">