我正在尝试将我们的构建从运行自定义.msbuild文件的CruiseControl.NET切换到Team Build 2010.正在编译的应用程序是一个VS2008解决方案,其中包含许多项目,其中两个是Web项目。
使用DefaultTemplate.xaml,似乎将两个Web项目部署到Binaries\_PublishedWebsites\(ProjectName)
。那个默认位置很好。但是,输出目录的内容似乎是可更新的,就好像aspnet_compiler.exe
调用-u
,或者<AspNetCompiler>
任务与Updateable="true"
一起使用。所以,有两个问题:
_PublishedWebsites
目录生成不可更新的输出?如何设置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文件?我可以使用的一些构建参数?如何更改上述构建步骤?
答案 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>
一些解释:
.csproj
文件正确地说,默认情况下C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets
正在使用。我以前没有意识到MSBuild知道如何使用.targets
文件。由于在VS2008下不使用目标文件的_CopyWebApplication
目标的唯一方法是不使用该文件,并且由于VS2010版本对我也没有帮助,我只是注释掉了导入。_CompiledWebsites
而不是_PublishedWebsites
。<BuildDependsOn>
元素,以便修改扩展点的任何其他项目文件都不会禁用我的目标。CompileWebsites
设置为true(使用类似于传递给MSBuild的/p:CompileWebsites=true
参数,但在Team Build中,如果需要,还有其他方法可以实现此目的)。这样,默认的本地构建不受影响。<Message>
元素用于调试。我在文件顶部附近的配置中将$(IsDebug)
设置为True或False。除了vanilla“Debug”和“Release”之外,我们有很多配置,所以这个标志是必要的,所以我可以告诉AspNetCompiler
是否包含调试符号。 $(IISVirtualPath)
也设置在文件顶部附近的配置中。有必要使IIS 6提供以这种方式编译的Web服务。AspNetCompiler
无法找到Team Build默认放置它们的预编译二进制文件,因此我将它们复制到项目的bin\
目录中,AspNetCompiler
期望找到它们。/p:CompileWebsites=True
参数。要完成此操作,请右键单击“团队资源管理器”窗口中的构建定义(在团队项目下的“构建”下),单击“处理”,展开“3.高级”条目,然后输入/p:CompileWebsites=True
作为标记为“的行” MSBuild Arguments“。如果我有两个以上需要此构建配置的项目,我可能会创建一个包含DoAspNetCompile
目标的文件并导入该文件。
答案 2 :(得分:2)
TFS 2010 Build中的DefaultTemplate.xaml仍然使用MSBuild来构建项目,因此如果您列出的两件事可以使用MSBuild.exe完成,则可以使用2010构建过程完成它们。您需要做的就是将您想要的MSBuild参数添加到构建定义的Process Parameters中。有关更新构建定义的更多详细信息,请参阅MSDN。