SandCastle - Yes it works!
RANK UPDATE ON PROJECT BHAL: 34th. on Popularity in CodePlex
The series of articles keep coming!
The series of the First Iteration will be:
- Continuous Integration with CodePlex - How, Tricks and Results
- SandCastle - Yes it works!
- Connection to TFS and WorkItem Creation Helper
- Creating a custom Windows Workflow Foundation Activity
So here is the second of the series.
SandCastle - Yes it Works!
Believe it or not, it works. It´s just hard to get it correctly configured by lack of documentation and tools to help guide you in this perilous journey.
First I want to make clear I´ve tried a couple tools for "automatically" building documentation with SandCastle and none appealed to me as I´m intending to implement the SandCastle task in the Continuous Integration process soon.
One tool I really liked is the SandCastle CreateBat project at code project.
This project creates a batch file with your specified configurations as to help you get the SandCastle process automated. Even though the batch file it generates does not work out of the box (maybe they´ll fix it soon), with a few minor modifications you are good to go.
But before I start to explain SandCastle integration I´d like to present a solution for placement of files that I found that helps a lot to keep documentation up-to-date with SandCastle.
Documentation Folder
The structure I suggest is:
----Your Code Folder Where your .sln file reside (in my case I called it Code)
----Documentation
This may not seem much to you as of now but you will understand later why keeping the documentation folder in the same level as your code folder helps a lot.
SandCastle Application
First you need to download and install both SandCastle CTP and HtmlHelp. Bear in mind that this article assumes you install them both in the default folder under Program Files. After you install both of them just keep going.
SandCastle Batch Files
Get the SandCastle CreateBat project at code project and let´s keep moving!
Now onto the SandCastle stuff. When you open the SandCastleCreateBat.exe application this is the screen you see:
Let´s say you have an assembly called C:\Development\SomeSolution\SomeProject\bin\Release\SomeProject.dll and the XML Comments are C:\Development\SomeSolution\SomeProject\bin\Release\SomeProject.xml. The CHM File will be C:\Development\Documentation\SomeProject.chm. Let´s check the Delete Working Files checkbox and click Create Bat. The following files will be created: sc_compile.bat and sandcastle.config. Those two files are the heart and soul of your SandCastle solution.
Let´s keep focused at the sc_compile.bat as the sandcastle.config should need no modifications at all.
Let´s open the sc_compile.bat and take a look at it:
if not exist output mkdir output
cd output
MRefBuilder "C:\Development\SomeSolution\SomeProject\bin\Release\SomeProject.dll" /out:reflection.org
if not exist comments mkdir comments
del comments\*.xml
copy "C:\Development\SomeSolution\SomeProject\bin\Release\SomeProject.xml" comments
XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\AddOverloads.xsl" reflection.org | XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\AddGuidFilenames.xsl" /out:reflection.xml
XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToManifest.xsl" reflection.xml /out:manifest.xml
if not exist html mkdir html
if not exist art mkdir art
if not exist scripts mkdir scripts
if not exist styles mkdir styles
copy "C:\Program Files\Sandcastle\Presentation\art\*" art
copy "C:\Program Files\Sandcastle\Presentation\scripts\*" scripts
copy "C:\Program Files\Sandcastle\Presentation\styles\*" styles
BuildAssembler /config:../sandcastle.config manifest.xml
XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToChmContents.xsl" reflection.xml /arg:html="html" /out:"Test.hhc"
if not exist help_proj.hhp copy "C:\Program Files\Sandcastle\Presentation\Chm\test.hhp" help_proj.hhp
"C:\Program Files\HTML Help Workshop\hhc.exe" "%CD%\help_proj.hhp"
@copy "Test.chm" "C:\Development\Documentation\SomeProject.chm"
@cd ..
@rd /s /q output
@pause
See, the paths we specified are all there, but there are some things we should watch out here. Since I´m dealing with a CodePlex project, where I don´t know what the root folder of the application code will be, it´s not cool to use physical paths, but in our case a Pure-Virtual path won´t make it either, so we combine the power of both and use the %CD% variable, like this:
"%CD%\..\..\SomeSolution\SomeProject\bin\Release\SomeProject.dll"
"%CD%\..\..\SomeSolution\SomeProject\bin\Release\SomeProject.xml" and
"%CD%\..\..\Documentation\SomeProject.chm"
This way, no matter where the person keeps the code, it will always build the correct documentation, as long as you use the SomeSolution folder in the same level as the Documentation folder.
There´s another issue in the code above. I painted the issues in red. This issue is due to the fact that the XslTransform command changed between SandCastle versions, and the Batch Builder hasn´t been update yet, but do not fear, you just have to tweak the syntax a little bit.
Let´s change the lines above like this:
XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\AddOverloads.xsl" reflection.org | XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\AddGuidFilenames.xsl" /out:reflection.xml
XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToManifest.xsl" reflection.xml /out:manifest.xml
becomes
XslTransform reflection.org /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\AddOverloads.xsl","C:\Program Files\Sandcastle\ProductionTransforms\AddGuidFilenames.xsl" /out:reflection.xml
XslTransform reflection.xml /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToManifest.xsl" /out:manifest.xml
and
XslTransform "C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToChmContents.xsl" reflection.xml /arg:html="html" /out:"Test.hhc"
becomes
XslTransform reflection.xml /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToChmContents.xsl" /arg:html="html" /out:"Test.hhc"
After these minor tweaks, you are all set with SandCastle batch file.
But we are not set yet, we still have to "help" SandCastle find the DLLs that your project references, so it can build the CHM properly. In order to do so, just set every single "Copy Local" property from the references in the project that you are building the documentation for to TRUE. I know that it sounds bad, but this helps SandCastle find the System.* dll´s and build a correct documentation for you.
Now you are set, just run the batch file and if everything goes well you should get a SomeProject.chm in no time. If something goes wrong you can check what went wrong in the console dialog that stays open waiting for input.
I did set two batch files for Project BHAL, one for the TFS Helper namespace and the other for the Custom Activity Library, so in order to help me build documentation easier I created a UpdateDocumentation.bat file that calls upon both, and removed the @pause from the bat files (only do that after certifying that the documentation is being built correctly!).
Well, till next article!
