First, we created a cmd file to do the build for us. Syntax for calling the file is Build.cmd "PathToBinaries" "Name of the documentation" (more on this later)

@echo off

PUSHD %1

"%programfiles%\Sandcastle\ProductionTools\mrefbuilder.exe" *.dll /out:%~dp0\reflection.org /dep:%windir%\Microsoft.NET\Framework\v2.0.50727\*.dll,C:\deps\*.dll,%WINDIR%\assembly\GAC_MSIL\Microsoft.VisualStudio.QualityTools.UnitTestFramework\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll

IF ERRORLEVEL 1 EXIT /B 1

POPD

"%programFiles%\Sandcastle\ProductionTools\XslTransform.exe" /xsl:"%programfiles%\Sandcastle\ProductionTransforms\AddOverloads.xsl" /xsl:"%programfiles%\Sandcastle\ProductionTransforms\AddGuidFilenames.xsl" reflection.org /out:reflection.xml

IF ERRORLEVEL 1 EXIT /B 1

"%programFiles%\Sandcastle\ProductionTools\XslTransform.exe" /xsl:"%programfiles%\Sandcastle\ProductionTransforms\ReflectionToManifest.xsl" reflection.xml /out:manifest.xml

IF ERRORLEVEL 1 EXIT /B 1

if not exist Output mkdir Output
if not exist Output\html mkdir Output\html
if not exist Output\art mkdir Output\art
if not exist Output\scripts mkdir Output\scripts
if not exist Output\styles mkdir Output\styles
copy "%programfiles%\Sandcastle\Presentation\art\*" Output\art > NUL
copy "%programfiles%\Sandcastle\Presentation\scripts\*" Output\scripts > NUL
copy "%programfiles%\Sandcastle\Presentation\styles\*" Output\styles > NUL

"%programfiles%\Sandcastle\ProductionTools\BuildAssembler.exe" /config:sandcastle.config manifest.xml
IF ERRORLEVEL 1 EXIT /B 1

"%programFiles%\Sandcastle\ProductionTools\XslTransform.exe" /xsl:"%programfiles%\Sandcastle\ProductionTransforms\ReflectionToChmProject.xsl" reflection.xml /out:Output\%2.hhp

IF ERRORLEVEL 1 EXIT /B 1

"%programFiles%\Sandcastle\ProductionTools\XslTransform.exe" /xsl:"%programfiles%\Sandcastle\ProductionTransforms\ReflectionToChmContents.xsl" reflection.xml /arg:html=Output\html /out:Output\%2.hhc

IF ERRORLEVEL 1 EXIT /B 1

"%programFiles%\Sandcastle\ProductionTools\XslTransform.exe" /xsl:"%programfiles%\Sandcastle\ProductionTransforms\ReflectionToChmIndex.xsl" reflection.xml /out:Output\%2.hhk

IF ERRORLEVEL 1 EXIT /B 1

CD OUTPUT

"%programfiles%\HTML Help Workshop\hhc.exe" %2.hhp

CD ..

 

There is also a configuration file we're using referenced in our call to BuildAssembler.exe; here is that

<configuration>

  <dduetools>

    <builder>

      <components>

        <!-- Create skeleton document -->

        <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

      <data file="%programfiles%\Sandcastle\Presentation\transforms\skeleton.xml" />

      <copy source="/*" target="/" />

    </component>

        <!-- Copy in reflection data -->

    <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">

            <data files="reflection.xml" />

          </index>

          <copy name="reflection" source="*" target="/document/reference" />

    </component>

    <!-- Copy in container data -->

    <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <copy name="reflection" key="string(/document/reference/containers/container/@namespace)" source="*[not(local-name()='elements')]" target="/document/reference/containers/container[@namespace]" />

    </component>

    <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <copy name="reflection" key="string(/document/reference/containers/container/@type)" source="*[not(local-name()='elements')]" target="/document/reference/containers/container[@type]" />

    </component>    

    <!-- Generate syntax -->

    <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

      <if condition="not(starts-with($key,'Overload:') or starts-with($key,'R:'))" />

          <then>

      <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

        <syntax input="/document/reference" output="/document/syntax" />

        <generators>

              <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\SyntaxGenerators.dll" />

              <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\SyntaxGenerators.dll" />

              <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\SyntaxGenerators.dll" />

            </generators>

          </component>

          </then>

    </component>

    <!-- Copy in comments -->

    <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <index name="comments" value="/doc/members/member" key="@name" cache="100">

            <data files="Documentation\*.xml" />

          </index>

          <copy name="comments" source="*" target="/document/comments" />

    </component>

    <!-- Copy in reflection data and comments for members -->

        <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <variable expression="/document/reference/elements/element/@api" />

          <components>

            <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <copy name="reflection" source="*[not(local-name()='elements')]" target="/document/reference/elements/element[@api=$key]" />

        </component>

            <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

              <copy name="comments" source="summary" target="/document/reference/elements/element[@api=$key]" />

            </component>

          </components>

        </component>

    <!-- transform -->

        <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <transform file="%programfiles%\Sandcastle\Presentation\transforms\main_sandcastle.xsl" />

        </component>

    <!-- resolve shared content -->

        <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <content file="%programfiles%\Sandcastle\Presentation\content\shared_content.xml" />

          <content file="%programfiles%\Sandcastle\Presentation\content\reference_content.xml" />

    </component>

    <!-- resolve reference links -->

    <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

      <targets files="reflection.xml" type="local" />

    </component>

    <!-- save the result -->

        <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%programfiles%\Sandcastle\ProductionTools\BuildComponents\BuildComponents.dll">

          <save path="concat('Output\html\',/html/head/meta[@name='guid']/@content,'.htm')" indent="false" omit-xml-declaration="true" />

        </component>

      </components>

    </builder>

  </dduetools>

</configuration>

 

Now we have to hook it up to MSBuild. Within the TFSProj.proj file, a new target was created called by an override to the Team Build AfterDrop target

<PropertyGroup>

    <SandcastleDocumentDirectory>$(TEMP)\SandcastleDocument</SandcastleDocumentDirectory>

</PropertyGroup>

<Target Name="SandcastleDocument">    

    <CreateProperty Value="MyDocumentation">

      <Output TaskParameter="Value" PropertyName="SandcastleDocumentationName"/>

    </CreateProperty>

    <RemoveDir Condition="Exists('$(SandcastleDocumentDirectory)')" Directories="$(SandcastleDocumentDirectory)" ContinueOnError="false"/>

    <MakeDir Directories="$(SandcastleDocumentDirectory)" ContinueOnError="false" />

    <CreateItem Include="$(SolutionRoot)\Sandcastle\Aug 2006 CTP\Build.cmd">

      <Output ItemName="SandcastleBuildScript" TaskParameter="Include"/>

    </CreateItem>

    <Copy SourceFiles="@(SandcastleBuildScript)" DestinationFiles="@(SandcastleBuildScript -> '$(SandcastleDocumentDirectory)\Build.cmd')" ContinueOnError="false" />

 

    <CreateItem Include="$(SolutionRoot)\Sandcastle\Aug 2006 CTP\sandcastle.config">

      <Output ItemName="SandcastleConfiguration" TaskParameter="Include"/>

    </CreateItem>

    <Copy SourceFiles="@(SandcastleConfiguration)" DestinationFiles="@(SandcastleConfiguration -> '$(SandcastleDocumentDirectory)\sandcastle.config')" ContinueOnError="false" />

 

    <MakeDir Directories="$(SandcastleDocumentDirectory)\Documentation" ContinueOnError="false"/>

    <CreateItem Include="$(BinariesRoot)\x86\Debug\*.xml">

      <Output ItemName="CodeDocumentationFiles" TaskParameter="Include"/>

    </CreateItem>

    <Copy SourceFiles="@(CodeDocumentationFiles)" DestinationFiles="@(CodeDocumentationFiles -> '$(SandcastleDocumentDirectory)\Documentation\%(Filename)%(Extension)')" ContinueOnError="false"/>

 

    <Exec WorkingDirectory="$(SandcastleDocumentDirectory)" Command="Build.cmd &quot;$(BinariesRoot)\x86\Debug&quot; $(SandcastleDocumentationName)" ContinueOnError="false" />

 

    <CreateItem Include="$(SandcastleDocumentDirectory)\output\$(SandcastleDocumentationName).chm" ContinueOnError="false">

      <Output ItemName="SandcastleDocumentationFiles" TaskParameter="Include"/>

    </CreateItem>

    <MakeDir Condition="!Exists('$(BinariesRoot)\Documentation')" Directories="$(BinariesRoot)\Documentation" ContinueOnError="false" />

    <Copy SourceFiles="@(SandcastleDocumentationFiles)" DestinationFiles="@(SandcastleDocumentationFiles -> '$(BinariesRoot)\Documentation\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" />

 

    <OnError ExecuteTargets="OnBuildBreak;"/>

  </Target>