4

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

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

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

    <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 文件?我可以使用的一些构建参数?如何更改上述构建步骤?

4

3 回答 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>
于 2012-03-01T21:03:45.480 回答
4

KMoraz 为我指明了正确的方向,我必须做更多的事情才能让它发挥作用。我真的不想编辑内置.targets文件,因为这会给不知道我做了什么的其他开发人员带来一些维护问题。我最终编辑了.csproj这两个 Web 应用程序的文件,<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(使用类似于/p:CompileWebsites=true传递给 MSBuild 的参数,尽管在 Team Build 中,如果需要,还有其他方法可以完成此操作)。这样,默认的本地构建不受影响。
  5. 这些<Message>元素用于调试。我$(IsDebug)在文件顶部附近的配置中设置为 True 或 False。除了普通的“调试”和“发布”之外,我们还有很多配置,所以这个标志是必要的,所以我可以判断AspNetCompiler是否包含调试符号。 $(IISVirtualPath)也在文件顶部附近的配置中设置。IIS 6 必须为以这种方式编译的 Web 服务提供服务。
  6. AspNetCompiler找不到 Team Build 默认放置的预编译二进制文件,因此我将它们复制到bin\项目的目录中,AspNetCompiler希望在其中找到它们。
  7. 我不需要对 Team Build 中的 .xaml 模板做任何特别的事情来让它工作。我确实必须确保构建定义包含/p:CompileWebsites=True参数。为此,请右键单击 Team Explorer 窗口中的构建定义(在您的团队项目下的 Builds 下),单击“Process”,展开“3. Advanced”条目,然后输入/p:CompileWebsites=True标记为“MSBuild Arguments”的行。

如果我有两个以上的项目需要此构建配置,我可能会使用DoAspNetCompile目标创建一个文件并导入该文件。

于 2012-03-07T20:47:34.310 回答
2

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

于 2012-02-23T20:19:09.327 回答