如何使Team Build 2010将Web应用程序发布为不可更新的?

4
我试图从运行自定义.msbuild文件的CruiseControl.NET切换到Team Build 2010来构建应用程序,这个应用程序是一个VS2008解决方案,其中包含多个项目,其中两个是Web项目。
使用DefaultTemplate.xaml,似乎这两个Web项目被部署到了 Binaries\_PublishedWebsites\(ProjectName)。这个默认位置很好。然而,输出目录的内容似乎可以更新,就像使用了-u调用了aspnet_compiler.exe一样,或者就像使用了<AspNetCompiler>任务,并设置Updateable="true"一样。所以,有两个问题:
  1. How do I make Team Build produce non-updateable output to the _PublishedWebsites directory?
  2. How can I also set the IIS VirtualPath as if I was doing the following in an MSBuild task:

    <AspNetCompiler Clean="true" Force="true" VirtualPath="/My-IIS-Virtual-Path" />
    
我以前在故障排除中发现,只有通过在命令中指定虚拟路径,才能让IIS 6以不可更新模式提供使用aspnet_compiler.exe编译的Web服务,这就是为什么我问问题#2的原因。
编辑:看到迄今为止的唯一答案后,我意识到我应该更清楚地说明问题。我知道如果我可以在MSBuild中做一些事情,我可以从构建模板中调用MSBuild。但是,我想知道更多关于如何更改将输出复制到_PublishedWebsites目录的内容。 "查找复制网站的任务并更改它"会很好用,但是我没有看到实际上将输出复制到_PublishedWebsites中的内容。我真正想做的是修改模板中完成此操作的步骤。
构建日志引用了一个名为_CopyWebApplication的编译目标,它似乎完成了复制Web应用程序所需文件的工作。但是,我不确定如何修改此编译目标,因为我在构建模板中或解决方案中的任何文件中都没有看到它。此外,无论运行_CopyWebApplication的是什么,它似乎仅针对Web应用程序项目运行,而不是解决方案中的许多其他项目。这是一件好事,但我不知道确定是否使用_CopyWebApplication的逻辑存在于何处。
也许有一些默认的MSBuild文件我错过了吗?我可以使用某些构建参数吗?如何修改上述构建步骤?
3个回答

4

_CopyWebApplication目标的所有逻辑都定义在以下位置:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets

目标本身相当简单,但它需要满足一堆前提条件:
<Target Name="_CopyWebApplication" 
        Condition="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'" 
        DependsOnTargets="$(_CopyWebApplicationDependsOn)">

  <CallTarget Condition="'$(OnAfter_CopyWebApplication)' != ''" Targets="$(OnAfter_CopyWebApplication)" RunEachTargetSeparately="true" />

</Target>

一旦到达所需的标志集,您就可以控制该过程。以下是默认值:

<WebProjectOutputDirInsideProjectDefault>True</WebProjectOutputDirInsideProjectDefault>
<WebProjectOutputDirInsideProjectDefault  Condition="('$(OutDir)' != '$(OutputPath)') Or ('$(IsDesktopBuild)' == 'False')" >False</WebProjectOutputDirInsideProjectDefault>
<DisableLinkInCopyWebApplicaton Condition="'$(DisableLinkInCopyWebApplicaton)'==''">False</DisableLinkInCopyWebApplicaton>
<Disable_CopyWebApplication Condition="'$(Disable_CopyWebApplication)' == ''">False</Disable_CopyWebApplication>
<UseWPP_CopyWebApplication Condition="'$(UseWPP_CopyWebApplication)' == ''">False</UseWPP_CopyWebApplication>
<CleanWebProjectOutputDir>True</CleanWebProjectOutputDir>
<CleanWebProjectOutputDir Condition="$(WebProjectOutputDirInsideProject)" >False</CleanWebProjectOutputDir>

1
现在我们有了一些进展,但是是否可以在不编辑文件的情况下实际更改默认标志呢? 我认为使用/p:Disable_CopyWebApplication = True作为MSBuild参数就可以解决问题,但是到目前为止,无论我尝试在哪里设置参数,它都没有停止_CopyWebApplication目标。 停止它可能是可以接受的,因为这样做后,简单地添加一个MSBuild步骤以进行AspNetCompile会更容易一些。 - Andrew
Disable_CopyWebApplication=True 禁止发布 Web 应用程序。您确定看到的二进制文件不是来自上一次运行吗?同时尝试传递 IsDesktopBuild=True - KMoraz
在进行更多测试时发现了问题的一部分... 团队构建正在使用v9.0目标文件,而不是v10.0。这很有道理,因为它是一个VS2008解决方案。乍一看,我没有看到类似的参数。 - Andrew
这些参数是在VS2010中引入的。您可以将其重定向到.csproj中的更新目标文件,如下所示:<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />。请确保它在客户端和构建服务器上都存在。或者也可以更新服务器端。这篇文章可能会有所帮助。 - KMoraz

4

KMoraz 指引了我正确的方向,但我还需要做更多的事情来使它正常工作。我真的不想编辑内置的 .targets 文件,因为这会在以后对其他开发人员产生一些维护问题,他们可能不知道我所做的事情。最终,我编辑了两个 Web 应用程序的 .csproj 文件,从文件末尾开始,从默认的 <Import> 元素开始,并在默认的 <ProjectExtensions> 元素之前结束:

  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- Since this Import serves no real purpose in VS2008 under Team Build, I'm commenting it out to remove
       a _CopyWebApplication step that we don't want.
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
  -->
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
  <!-- Now, for Team Build, do the AspNetCompile steps ourselves. -->
  <PropertyGroup>
      <WebProjectOutputDir Condition="'$(OutDir)' != '$(OutputPath)'">$(OutDir)_CompiledWebsites\$(MSBuildProjectName)</WebProjectOutputDir>
  </PropertyGroup>
  <PropertyGroup>
      <BuildDependsOn>
          $(BuildDependsOn);
          DoAspNetCompile
      </BuildDependsOn>
  </PropertyGroup>
  <Target Name="DoAspNetCompile" Condition="'$(CompileWebsites)' == 'True' And '$(OutDir)' != '$(OutputPath)'">
      <Message Text="Performing AspNetCompile step for $(MSBuildProjectName)" />
      <Message Text="Output will have IIS virtual directory '$(IISVirtualPath)'" />
      <Message Text="ProjectDir is $(ProjectDir)" />
      <Message Text="IsDebug is $(IsDebug)" />
      <RemoveDir Directories="$(WebProjectOutputDir)" ContinueOnError="true" />
      <MakeDir Directories="$(WebProjectOutputDir)" />
      <!-- We need the /bin directory, populated with some DLLs and PDBs -->
      <CreateItem Include="$(OutDir)*.dll;$(OutDir)*.pdb">
          <Output TaskParameter="Include" ItemName="BinariesToCopy" />
      </CreateItem>
      <Copy DestinationFolder="$(ProjectDir)\bin" SourceFiles="@(BinariesToCopy)" />
      <AspNetCompiler Clean="True" Force="True" Debug="$(IsDebug)" Updateable="False" VirtualPath="$(IISVirtualPath)" PhysicalPath="$(ProjectDir)" TargetPath="$(WebProjectOutputDir)" />
  </Target>

一些解释:
  1. 正如您所看到的,.csproj文件中明确指出,默认情况下使用C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets。我之前没有意识到这就是MSBuild知道要使用该.targets文件的方式。由于在VS2008下唯一不使用目标文件_CopyWebApplication的方法是不使用该文件,而且由于VS2010版本对我也没有帮助,所以我只是注释掉了导入。
  2. 为了将我的输出与默认输出区分开来,我将输出目录的名称更改为_CompiledWebsites而不是_PublishedWebsites
  3. 我添加了<BuildDependsOn>元素,以便以后修改扩展点的任何其他项目文件都不会禁用我的目标。
  4. 我确实要求CompileWebsites设置为true(使用类似于通过MSBuild传递的/p:CompileWebsites=true参数,虽然在Team Build中,如果需要,还有其他方法可以实现此目的)。这样,缺省的本地构建就不受影响。
  5. <Message>元素用于调试。我在文件顶部的配置中将$(IsDebug)设置为True或False。我们除了基本的“Debug”和“Release”之外还有许多其他配置,因此必须使用此标志来告诉AspNetCompiler是否包含调试符号。$(IISVirtualPath)也在文件顶部的配置中设置。这是必要的,以便IIS 6可以提供以这种方式编译的Web服务。
  6. AspNetCompiler找不到Team Build默认放置预编译二进制文件的位置,因此我将它们复制到项目的bin\目录中,AspNetCompiler期望在那里找到它们。
  7. 我没有对Team Build中的.xaml模板做任何特殊处理就使其工作。我确实必须确保构建定义包括/p:CompileWebsites=True参数。要实现这一点,请在Team Explorer窗口中右键单击构建定义(在您的团队项目下的“构建”下),单击“进程”,展开“3.高级”条目,并在标记为“MSBuild参数”的行中输入/p:CompileWebsites=True

如果我有超过两个需要这种构建配置的项目,我可能会创建一个带有DoAspNetCompile目标的文件并导入该文件。


2

TFS 2010 Build的DefaultTemplate.xaml仍然使用MSBuild来构建您的项目,因此如果您列出的两件事可以使用MSBuild.exe完成,则可以使用2010构建过程完成。您只需要将想要的MSBuild参数添加到构建定义的Process Parameters中即可。有关更新构建定义的更多详细信息,请参阅MSDN


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