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

时间:2012-02-23 19:11:01

标签: tfs2010 asp.net-3.5 team-build aspnet-compiler

我正在尝试将我们的构建从运行自定义.msbuild文件的CruiseControl.NET切换到Team Build 2010.正在编译的应用程序是一个VS2008解决方案,其中包含许多项目,其中两个是Web项目。

使用DefaultTemplate.xaml,似乎将两个Web项目部署到Binaries\_PublishedWebsites\(ProjectName)。那个默认位置很好。但是,输出目录的内容似乎是可更新的,就好像aspnet_compiler.exe调用-u,或者<AspNetCompiler>任务与Updateable="true"一起使用。所以,有两个问题:

  1. 如何让Team Build为_PublishedWebsites目录生成不可更新的输出?
  2. 如何设置IIS VirtualPath,就好像我在MSBuild任务中执行以下操作一样:

    <AspNetCompiler Clean="true" Force="true" VirtualPath="/My-IIS-Virtual-Path" />
    
  3. 我在早期的故障排除中发现,我可以让IIS 6在不可更新模式下使用aspnet_compiler.exe提供服务的Web服务的唯一方法是在命令中指定虚拟路径,这就是我的原因询问#2。

    修改

    到目前为止看到一个答案,我意识到我应该更清楚这个问题是什么。我意识到,如果我可以在MSBuild中做一些事情,我可以从构建模板中调用MSBuild。但是,我想知道如何更改将输出复制到_PublishedWebsites目录的情况。 “找到复制网站并更改它的任务”会很有效,除了我没有看到实际上将输出复制到_PublishedWebsites的内容。我真正想做的是修改模板中完成此步骤的步骤。

    构建日志引用名为_CopyWebApplication的编译目标,该目标似乎可以复制Web应用程序所需的文件。但是,我不确定如何修改此编译目标,因为我在构建模板中的任何位置都没有看到它,也没有在解决方案的任何文件中看到它。此外,无论运行_CopyWebApplication似乎只运行Web应用程序项目,而不是解决方案中的许多其他项目。这是一件好事,除了我不知道存在哪个逻辑决定是否使用_CopyWebApplication

    也许我缺少一些默认的MSBuild文件?我可以使用的一些构建参数?如何更改上述构建步骤?

3 个答案:

答案 0 :(得分: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 :(得分: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。除了vanilla“Debug”和“Release”之外,我们有很多配置,所以这个标志是必要的,所以我可以告诉AspNetCompiler是否包含调试符号。 $(IISVirtualPath)也设置在文件顶部附近的配置中。有必要使IIS 6提供以这种方式编译的Web服务。
  6. AspNetCompiler无法找到Team Build默认放置它们的预编译二进制文件,因此我将它们复制到项目的bin\目录中,AspNetCompiler期望找到它们。
  7. 我没有对Team Build中的.xaml模板做任何特殊处理,以使其工作。我必须确保构建定义包含/p:CompileWebsites=True参数。要完成此操作,请右键单击“团队资源管理器”窗口中的构建定义(在团队项目下的“构建”下),单击“处理”,展开“3.高级”条目,然后输入/p:CompileWebsites=True作为标记为“的行” MSBuild Arguments“。
  8. 如果我有两个以上需要此构建配置的项目,我可能会创建一个包含DoAspNetCompile目标的文件并导入该文件。

答案 2 :(得分:2)

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