Joe in Iowa – A Sandcastle Scenario

This post provides steps to create CHM using Sandcastle. Some of the users have automated these steps. Mikael Söderström has a “Sandcastle Helper” here, Ashley van Gerven has a batch script available here and Scott Hanselman’s has power shell script available here. Frank Kroondijk has created a Sandcastle VS 2005 add-in here.

Anders Ljusberg has some interesting finds about Sandcastle here.


Sandcastle installation adds the various tools to your path. Alternatively in the Sandcastle Examples directory, invoke setPath.bat to add the sandcastle tools to your path. Then create a subdirectory for your project and cd into it. Several of the command-line arguments and batch files referenced in the following instructions use relative path expressions that assume this directory structure. You are welcome to use a different directory structure, but if you do so you will need to change those relative path expressions.


In this post I wanted to capture “Joe in Iowa”, an user scenario for Sandcastle and provide some additional details.


Joe in Iowa: “I’m one of four developers on our team creating reusable web controls. We write our own documentation inline using C# XML documentation comments. It’s really convenient and we can see our real documentation in seconds using Sandcastle. Our customers really love the MSDN-like documentation.”


Consider the case of Joe generating documentation for a managed assembly A.dll. Suppose A.dll depends on assemblies B.dll and C.dll. (That is, classes in A.dll inherit from types in B.dll and C.dll, or APIs in A.dll use types in them as parameter and return types.).


The first step in the sandcastle process is to generate reflection data files for the assemblies. To generate a reflection data file for A.dll Joe executes the following command:


MRefBuilder A.dll /dep:B.dll,C.dll /


Joe can also use wildcards. For example, if Joe’s assemblies to document are in the dll subdirectory and their dependencies are in the dep subdirectory, he can generate reflection data like this:


MRefBuilder dll\*.dll /dep:dep\*.dll /


The output of MRefBuilder contains information about each API in the reflected assemblies.


If Joe is not sure on which assemblies A.dll depends, he can just go ahead an invoke MRefBuilder with A.dll. If it finds that it needs another one, it will emit an error message identifying the additional dependency assembly that it requires. Joe does not need to provide core .NET Framework assemblies (e.g. mscorlib.dll) that an assembly depends on; MRefBuilder will fetch those from your .NET Framework installation directory.


The reflection information file contains information on each API that MRefBuilder found, but to generate documentation Joe needs a file that contains information on each topic that will appear in his documentation. To generate such a file, Joe needs to apply a few transformations:


          XslTransform ..\..\ProductionTransforms\AddOverloads.xsl |

          XslTransfrom ..\..\ProductionTransforms\AddGuidFilenames.xsl



These transforms add pseudo-API topics corresponding to overload pages and information about the name of the file in which the topic will be stored. (Why not have MRefBuilder generate this information directly? We wanted to allow the “documentation model” to change without having to change the “reflection step”. If someone decides on documentation model without overloads, or wants to change the file naming convention, that shouldn’t require changing the reflection process.)


The next step in the sandcastle process is to use the reflection data file to generate a manifest of topics to be generated. This is done by applying a transform to the reflection data:


XslTransform ..\..\ProductionTranforms\ReflectionToManifest.xsl reflection.xml          /out:manifest.xml


Joe examines the manifest, and notices it is a very simple XML file that lists the ID of each topic to be generated. (If you ever want to build just a handful of topics, it should be easy to construct such a manifest by hand. If you ever develop a complex process that might require you to generate a subset or superset of the topics that this transform produces, it should be a straightforward task to automate the generation of the corresponding manifest.)


Joe is ready to generate topic pages. He needs to create a directory structure to contain them and the associated image, script, and style files. Sandcastle provides a script that creates this structure. Joe executes this script and creates an output directory structure:




Now, Joe is ready to generate HTML documentation pages. To do so, he invokes the BuildAssembler tool using the following command:


          BuildAssembler /config:..\..\Presentation\configuration\sandcastle.config



You should see informational messages indicating that BuildAssembler is loading data, then generating topics pages. The output pages will appear in the Output\html subdirectory. Joe opens them in a web browser and peruses the fruits of his labor.


BuildAssembler is the heart of the sandcastle documentation process; all the steps Joe has taken up to now just generate files containing the information that BuildAssembler needs. These files are referenced in the sandcastle.config configuration file.


Packaging: Most documentation is delivered as CHM/HxS files. This section explains how to package the output of the sandcastle tool-chain into such a container. The necessary help compilers are not a part of sandcastle, but are available from:


Microsoft HTML Help 1.x Compiler – The HTML Help Compiler for HTML Help 1.x can be downloaded as part of the Microsoft HTML Help Workshop from

Microsoft Help 2.0 Compiler – The Help Compiler for Help 2 is part of the Microsoft Visual Studio 2003 .NET Help Integration Kit.


hhc (HTML Help 1.x Compiler):

The CHM compiler hhc.exe requires as input a project (HHP) file and a table of contents (HHC) file. Joe can generate a custom HHP or can copy the HHP template provided by Sandcastle:


copy ..\..\Presentation\chm\test.hhp Output


Joe can execute HHC from the topic data file via a transformation:


          XslTransform ..\..\ProductionTransforms\ReflectionToChmContents.xsl

          reflection.xml /out:Output\test.hhc


After generating these file, Joe can run the CHM compiler:


          cd Output


and then


          hhc.exe test.hhp


This creates the file test.chm containing his documentation.


HxComp (Microsoft Help 2.0 Compiler):  

HxComp compiles the Sandcastle target files into an HxS/HxI pair of files. The HxS generation requires a few more project definition files than the CHM case. Sandcastle provides these definition files. Joe begins by executing a script to copy these definition files in to the output directory:




Like the CHM case, though, Joe must create file that defines the packaged table of contents (HxT). This is accomplished by a simple transform of the reflection data file.


XslTransform ..\..\ProductionTransforms\ReflectionToHxSContents.xsl reflection.xml /out:Output\test.HxT


Finally, Joe invokes the Help 2.0 compiler to create an HxS file.


cd Output


and then


hxcomp –p test.HxC –l test.log


This creates the file test.hxs containing his documentation.

Comments (11)

  1. RubenP says:

    Just wondering, but does Sandcastle support real HTML docs (or HTML + JavaScript docs) like MSDN online? NDoc did (really well), and so does JavaDoc (a little less well), and I must say, that’s a real ‘selling point’ for me. And I mean by default, not a pointer to some blog that tells you roughly how to reinvent the wheel by yourself, but leaves the complete working solution as an excercise to the reader. 😉

    I really *hate* it if I need to download a CHM or MSI file and deal with all the security worries that such a method entails. (CHM’s are a security breach waiting to happen and you usually need admin rights to run an MSI). And Document Explorer is just so insanely slow to use. I want to *read* documentation, not wait a minute before the viewer it finally starts and even then wait 5 seconds between each page transition.

    But with a website, you just point yourself (or a customer) to a url and hey presto. Compiling plain HTML pages is a lot faster when you’re fixing up your documentation. Refresh – check – fix – compile – refresh … The HTML Help compiler requires you to close your files when you’re compiling, and takes ages to complete. (Hmmm, I’m starting to see a pattern here…)

  2. Sandcastle generated HTM files. If you look at this blog it’s eamplained above the "Packaging" section.

  3. Sandcastle generated HTM files. If you look at this blog it’s explained above the "Packaging" section.

  4. RubenP says:

    Well, you’ve got HTML and you’ve got HTML. I don’t expect to be using the same HTML for a CHM or a website; are you? Could you perhaps post an example of an in-box pure HTML run *as a web site* as opposed to a bunch of files?

    Still a bit in the wait-and-see mode, with the early-but-not-wholly-unexpected demise of NDoc.

  5. Ruben,

    We do not have an example which will generate an out of box ‘website" from Sandcastle. If you provide us a scenario I will be happy to consider this as  feature.


  6. RubenP says:

    Well, it seems this scenario is a little hard to grock unless you’ve seen it in action. Ever tried NDoc or JavaDoc? If you haven’t (being Microsoft employees and all), you really should.

    Wat you do with NDoc, is that you specify the XML comment file(s), and tell NDoc what parts of the object model you do and do not wish to generate documentation for (internals private methods, warnings for missing documentation, etc.) Then you select a template (such as MSDN-like), and after pressing the Build-button, NDoc generates all HTML files, with cross references, index pages, supporting JavaScript, css and images, and puts them in a directory (specified by the user). When NDoc is done, you just open index.html and you’ve got the complete documentation of your library at your fingertips, with a navigation pane, etc., except for a search-page.

    If you look at, you’ll find an example which was generated directly from the predefined MSDN template.

    You should also take a look at, especially the Tag reference, as the users of NDoc discovered that the standard comment tags are, erm, lacking. These extra tags were impemented mostly through extra XSLTs, but they were both documented and supported, so you didn’t have to re-invent the wheel every time.

    A full document builder is fine, but you do need to keep an eye out for the projects that don’t involve a team of 10+ documentation writers.

  7. Ruben,

    Thanks for your comments. I have not triend nDoc or Java Doc. However I will and it looks like we can address all the scenarios you have mentioned. We do plan to provide MSDN styled templates.

    As I mentioned at we do plan to support all additional tags including user defined tags.


  8. RubenP says:

    Great. Looking forward to the upcomming CTPs.

  9. Charlie Rieder says:


    have a look at

    IMHO Eric has created an excellent tool for Sandcastle, aimed at NDoc users.

  10. Sandcastle – December 2006 Community Technology Preview (CTP)を使ったメモ

    ※現状では、結局chmの作成はできなかったけど、とりあえずHTMLが作成できたからOKとしている状況。HTMLが2万近くあるからなんとかchmにしたいけれど。。。 作業ディレクトリは C:Program FilesSandcastleTESTDoc。 ソリューションが全部入っているディレクトリ以下に存在するdebugフォルダを全部作業ディレクトリにコピーする

Skip to main content