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文件添加到项目中。
通常你会有Debug
和Release
configuration,所以命名你的文件App.Debug.config
和App.Release.config
。 在我的项目中,我为每种环境创build了一个configuration,所以您可能想要尝试一下。
2.卸载项目并打开.csproj文件进行编辑
Visual Studio允许你在编辑器中编辑.csproj文件 – 你只需要先卸载项目。 然后右键单击它并select编辑<ProjectName> .csproj 。
3.将App。*。config文件绑定到主App.config
find包含所有App.config
和App.*.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')">