MSBuild脚本和VS2010发布应用Web.config变换

72

我已经安装了VS 2010,并正在修改MSBuild脚本以用于我们的TeamCity构建集成。除了一个问题,一切都很顺利。

我该如何告诉MSBuild,在发布构建时要应用我创建的Web.conifg变换文件...

我使用以下代码生成编译后的网站,但是它会将Web.config,Web.Debug.config和Web.Release.config文件(三个文件)输出到编译输出目录。当我在工作室中执行发布到文件系统时,它会执行变换并只输出具有适当更改的Web.config文件...

<Target Name="CompileWeb">
    <MSBuild Projects="myproj.csproj" Properties="Configuration=Release;" />
</Target>

<Target Name="PublishWeb" DependsOnTargets="CompileWeb">
    <MSBuild Projects="myproj.csproj"
    Targets="ResolveReferences;_CopyWebApplication"
    Properties="WebProjectOutputDir=$(OutputFolder)$(WebOutputFolder);
                OutDir=$(TempOutputFolder)$(WebOutputFolder)\;Configuration=Release;" />
</Target>

希望能得到任何帮助..!

我知道可以通过其他方式完成,但如果可能的话,我想使用新的VS 2010方法来实现


这是一篇关于自定义转换的优秀文章:http://www.diaryofaninja.com/blog/2011/09/14/using-custom-webconfig-transformations-in-msbuild 由于我们需要适应大量经典ASP和其他棘手问题,因此我们需要比通常更多地定制Web部署。这篇文章节省了数小时挖掘MS目标的时间。 - kenchilada
6个回答

63

我在寻找类似的信息时没有完全找到,所以我在Visual Studio 2010和MSBuild 4.0中的.targets文件中进行了一些挖掘。 我认为这是寻找执行转换的MSBuild任务的最佳位置。

据我所知,使用以下MSBuild任务:

<Project ToolsVersion="4.0"
         DefaultTargets="Deploy"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <UsingTask TaskName="TransformXml"
               AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

    <PropertyGroup>
        <ProjectPath>C:\Path to Project\Here</ProjectPath>
        <DeployPath>C:\Path to Deploy\There</DeployPath>
        <TransformInputFile>$(ProjectPath)\Web.config</TransformInputFile>
        <TransformFile>$(ProjectPath)\Web.$(Configuration).config</TransformFile>
        <TransformOutputFile>$(DeployPath)\Web.config</TransformOutputFile>
        <StackTraceEnabled>False</StackTraceEnabled>
    </PropertyGroup>


    <Target Name="Transform">
        <TransformXml Source="$(TransformInputFile)"
                      Transform="$(TransformFile)"
                      Destination="$(TransformOutputFile)"
                      Condition="some condition here"
                      StackTrace="$(StackTraceEnabled)" />
    </Target>
</Project>

我已经测试过上述内容并确认它可以工作。你可能需要稍微调整一下结构,以更好地适应你的构建脚本。


4
这与我最终使用的解决方案非常相似。唯一需要注意的是,TransformXml操作目前存在一个错误,它不会关闭源文件,因此您无法摆脱源文件。仅供参考:在我的情况下,在完成转换后,我希望从部署目录中删除Debug.config和Release.config文件。要解决这个问题,直到微软公司修复这个问题,您可以将源文件和转换文件复制到临时目录,然后将新转换的文件复制回来,然后您就可以删除/移除文件了... - xspydr
1
是的,当我尝试它时,我也遇到了那个bug。这就是为什么我不得不使用$(ProjectPath)和$(DeployPath)。实际上,我建议使用一个中间位置来收集所有的构建工件(包括Web.config文件),然后从包含所有工件的该位置部署到各个Web服务器。这将节省多次转换Web.config的时间,假设所有Web服务器都将采用完全相同的Web.config文件。 - Umar Farooq Khawaja
2
+1 感谢您解决了我的问题,该问题来源于 https://dev59.com/CU7Sa4cB1Zd3GeqP2Enp - Ryan M
对我来说完美运作,太棒了!所引用程序集的完整路径在此处(x64上):“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.Dll”。 - stephen
1
@Jason提到的那个bug现在已经解决了,我正在使用v12.0的msbuild.exe,它运行得非常好。 - Sarvesh

14

1
唯一的问题是这种方法不会将配置转换应用于连接字符串。 - Troy Hunt
所有的web.config转换都应该使用这种方法工作。为什么连接字符串特别不能工作? - pattersonc
3
由于连接字符串的处理方式不同,您会看到一个可替换的令牌: http://troy.hn/gYb7M5,除非您覆盖<AutoParameterizationWebConfigConnectionStrings>:http://troy.hn/mk8iJL。 - Troy Hunt
这会将它放在我的 bin 文件夹下面很多层深的某个非常随机的目录中。 - jjxtra
2
就像Troy上面建议的那样,我只是在我的msbuild命令中添加了/p:AutoParameterizationWebConfigConnectionStrings=False,现在包含了最终的web.config转换。 - Ben Cull

8

或者,您可以尝试使用XDT转换工具

https://github.com/greenfinch/ctt

我使用此工具而不是与晦涩的msbuild目标搞混。它适用于app.config而不仅仅是web.config


5

我用以下更改方法成功了

<MSBuild Projects="$(ProjectFile)"
         Targets="ResolveReferences;_WPPCopyWebApplication"
     Properties="WebProjectOutputDir=TempOutputFolder;OutDir=$(WebProjectOutputDir);Configuration=$(Configuration);" />

从 MsBuild 文件夹下的 Microsoft.WebApplication.targets 文件中

_CopyWebApplication

This target will copy the build outputs along with the 
content files into a _PublishedWebsites folder.

This Task is only necessary when $(OutDir) has been redirected
to a folder other than ~\bin such as is the case with Team Build.

The original _CopyWebApplication is now a Legacy, you can still use it by 
 setting $(UseWPP_CopyWebApplication) to true.
By default, it now change to use _WPPCopyWebApplication target in
 Microsoft.Web.Publish.targets.   
It allow to leverage the web.config trsnaformation.

我正在使用nant,但TransformWebConfig目标对我来说无法正常工作,直到我还添加了_WPPCopyWebApplication目标。这解决了我的问题。 - SouthShoreAK

0

0

在我搜索了好几天之后,我对这个问题有了另一个答案:

您的发布配置文件和配置名称应该匹配。

在我的情况下,它们并不匹配。通过发布配置文件手动发布给了我想要的结果,因为我的配置是在发布配置文件中设置的。然而,MSBuild试图变得智能,并根据名称神奇地连接发布配置文件和配置。(在命令中添加/p:Configuration导致其他关于引用项目输出路径的奇怪错误)。

只是为了确切地表达我的意思:

来自命令行的MSBuild语句

msbuild myproject.csproj -t:Clean -t:Rebuild /p:DeployOnBuild=true /p:PublishProfile="Development"

可行

  • 发布配置文件名称:Development
  • 解决方案配置名称:Development

不可行

  • 发布配置文件名称:Development
  • 解决方案配置名称:Dev

希望这可以帮助到您!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接