I'm trying to switch our build from CruiseControl.NET running a custom .msbuild file to Team Build 2010. The application being compiled is a VS2008 solution with numerous projects, two of which are web projects.
Using DefaultTemplate.xaml, it appears that the two web projects are deployed to Binaries\_PublishedWebsites\(ProjectName)
. That default location is fine. However, the contents of the output directories appear to be updateable, as though aspnet_compiler.exe
was called with -u
, or as though an MSBuild <AspNetCompiler>
task was used with Updateable="true"
. So, two questions:
_PublishedWebsites
directory?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" />
I have found in earlier troubleshooting that the only way I can get IIS 6 to serve a web service compiled with aspnet_compiler.exe
in non-updateable mode is to specify the virtual path in the command, which is why I am asking about #2.
Edit:
Upon seeing the one answer thus far, I realized I should have been much clearer about what the issue is. I realize that, if I can do something in MSBuild, I can just call MSBuild from the build template. However, I am wondering a little more about how change what happens to copy the output to the _PublishedWebsites
directory. "Find the task that copies the website and change it" would work well, except that I don't see what is actually copying the output into _PublishedWebsites
. What I'm really wanting to do is to modify the step in the template that accomplishes this.
The build log references a compile target called _CopyWebApplication
that appears to do the work of copying the files needed for a web application. However, I am unsure how to modify this compile target, as I do not see it anywhere in the build template nor in any file in the solution. Further, whatever runs _CopyWebApplication
appears to be running it only for web application projects, not the many other projects in the solution. This is a good thing, except that I do not know where the logic exists that determines whether to use _CopyWebApplication
.
Maybe there is some default MSBuild file that I am missing? Some build parameter that I could be using? How do I alter the aforementioned build step?
KMoraz pointed me in the right direction, and I had to do a few more things to get this working. I really did not want to edit the built-in .targets
files, since that would create some maintenance problems down the line for any other developer who did not know what I did. I ended up editing the .csproj
files for the two web applications to this, starting with the default <Import>
element near the end of the file and ending before the default <ProjectExtensions>
element:
<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>
Some explanations:
.csproj
file, as you can see, that C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets
is in use by default. I did not realize previously that was how MSBuild knew to use that .targets
file. Since the only way not to use the target file's _CopyWebApplication
target under VS2008 is not to use the file, and since the VS2010 version really did not help me either, I just commented out the import._CompiledWebsites
instead of _PublishedWebsites
.<BuildDependsOn>
element so that any other project files down the road that modify the extension points do not disable my target.CompileWebsites
is set to true (using something like the /p:CompileWebsites=true
parameter passed to MSBuild, though within Team Build, there are also other ways to accomplish this if desired). That way, the default local build is unaffected.<Message>
elements are for debugging. I have set $(IsDebug)
to True or False in the configurations near the top of the file. We have many configurations besides vanilla "Debug" and "Release", so this flag was necessary so I could tell AspNetCompiler
whether to include debugging symbols. $(IISVirtualPath)
is also set in the configurations near the top of the file. It is necessary so that IIS 6 will serve a web service compiled in this manner.AspNetCompiler
cannot find the precompiled binaries where Team Build puts them by default, so I copy them to the bin\
directory of the project, where AspNetCompiler
expects to find them./p:CompileWebsites=True
parameter. To accomplish this, right-click the build definition in the Team Explorer window (under Builds under your team project), click "Process", expand the "3. Advanced" entry, and enter /p:CompileWebsites=True
for the line labeled "MSBuild Arguments".If I had more than two projects that needed this build configuration, I would probably create a file with the DoAspNetCompile
target and import that file.