If you've ever used a library that has accurate MSDN-style API documentation, you know how useful it can be. There are lots of ways to create HTML documentation. But the easiest way that I've found is to use Sandcastle. It's an open source documentation generator from Microsoft that reads your assemblies (DLL or EXE files) and their XML Comments and automatically generates HTML documentation. Sandcastle is a very flexible tool, which means it's also a very complex tool. Luckily, there's a companion tool,Sandcastle Help File Builder, that makes it really easy to get up and running with Sandcastle in minutes.
This tutorial will walk you through creating simple HTML documentation for a class library. Here's what we'll do:
- Step 1: Install Sandcastle and Sandcastle Help File Builder
- Step 2: Create a file called Guy.cs with code to document
- Step 3: Compile the code into the Guy.dll assembly
- Step 4: Set up the Sandcastle Help File Builder project
- Step 5: Run Sandcastle
Plus, we'll take care of a few extra things:
- Fix
[Missing <summary> documentation]
Sandcastle problems - Add an AssemblyInfo.cs file to set assembly attributes
- Use MSBuild to run Sandcastle from the command line
- Using Sandcastle Help File Builder with a Visual Studio project
Step 1: Install Sandcastle and Sandcastle Help File Builder
Sandcastle is a really powerful and very flexible tool. It's also command-line based, without any sort of graphical front end. That's a combination that makes it very difficult to casually start using it. Like most software, an 80/20 rule applies to Sandcastle: 80% of the users only need to use 20% of its features. Luckily, there's a companion tool called Sandcastle Help File Builder that makes it extremely easy to access that 20%. With Sandcastle and Sandcastle Help File Builder (which I'll sometimes abbreviate as SHFB), you can start building help files and HTML documentation in minutes.
The first step is to download and install Sandcastle and Sandcastle Help File Builder:
- Use the Download link on the Sandcastle CodePlex page to download and run the installer for the latest stable release .
- Do the same for Sandcastle Help File Builder.
- Make sure you take note of the installation folders for both Sandcastle and Sandcastle Help File Builder. They're typically installed in
c:\Program Files
orc:\Program Files (x86)
—Sandcastle is usually in a folder calledSandcastle
, and SHFB is usually inEWSoftware\Sandcastle Help File Builder
.
Note that while Sandcastle and Sandcastle Help File Builder come with installers, they can both be installed by copying their contents to any folder you want. If you're working on a machine that's locked down so you can't install programs—a lot of computers at offices are locked down for security reasons—that can be very useful. It can also come in handy when you're generating HTML documentation from a continuous build that's running on a build server where you don't have administrator privileges.
Step 2: Create a file called Guy.cs with code to document
Sandcastle generates its documentation in two ways. It uses reflection to inspect the members of the public classes in the assemblies, and it reads the documentation generated in the XML comments.
When Sandcastle creates documentation from an assembly, it needs to find at least one namespace that contains at least one public class in it. If it doesn't, it will give you an error (which we'll see in a minute). So the first thing you need to do is prepare your code by adding XML comments.
(If you haven't used XML comments before, you can get a quick overview of them in myC# XML comments tutorial. And if you're a little confused about .NET assemblies and namespaces in C#, have a look at my C# and .NET assemblies and namespaces tutorial.)
For the first part of this tutorial, we'll be doing everything from the command prompt. So for now, you should use Notepad to edit the source file that we create. Everything in this post works equally well in Visual Studio. I'm concentrating on the command line, because a lot of people need to know how to create documentation as part of an automated build, and that typically requires using commands that you run from a command prompt. A lot of .NET developers haven't spent much time using the command prompt. If you haven't, don't worry—just check out this section of a post on compiling and running C# code from a command prompt.
I've already got a class prepared that has XML comments in it. It's my my simple utility class called Guy. Go ahead and copy the Guy.cs code from that link, paste it into Notepad, and save it as a file called Guy.cs.
Notice how the Guy class uses string and Console? These are part of the System namepsace, so to avoid compile errors add this line to the top of the Guy.cs file:
using System;
Your code is now ready to compile. (You might have noticed a slight problem with it that will cause problems with Sandcastle—we'll fix it in a minute.)
Step 3: Compile the code into the Guy.dll assembly
Now we're ready to compile that code using CSC, the command-line C# compiler. Here's how to run it:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\csc.exe
If you get a "The system cannot find the path specified" error, replace v4.0.30319
with v3.5
in the command line. Everything in this tutorial will work with .NET 3.5.That's the version number of the .NET Framework being used—v4.0.30319 is .NET Framework 4.0. Everything in this tutorial works just fine with .NET 3.5, so if you've got that installed you can run it by replacing v4.0.30319 with v3.5. Alternately, if you've got Visual Studio installed, you can start the Visual Studio Command Prompt, and csc.exe is in the path. (This isn't available if you're running the the Express edition.)
Open a command prompt and navigate to the folder where you saved Guy.cs. Run the following command:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library /doc:Guy.xml Guy.cs
Here's what it should look like (I saved my Guy.cs file in c:\temp\Guy):
When you ran csc.exe, it created two files: Guy.dll (the assembly that contains the Guy class) and Guy.xml (which contains the documentation generated from the XML comments).
Step 4: Set up the Sandcastle Help File Builder project
To run Sandcastle Help File Builder, you just need to set a few variables and then run SandcasteBuilderGUI. The easiest way to do it is to paste these four commands into the command prompt:
set DXROOT=c:\Program Files (x86)\Sandcastle
set SHFBROOT=c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder
set LANGUAGE=
"%SHFBROOT%\SandcastleBuilderGUI.exe"
(You can paste into the command prompt by clicking on the Windows menu icon in the upper right-hand corner of the window and selecting Edit >> Paste.)
When the Sandcastle Help File Builder window opens, choose File >> New Project from the menu. Name it Guy.shfbproj (that's the normal extension for SHFB projects). Here's what the new SHFB project should look like:
Next you need to tell SHFB where to find the DLL and XML file that Sandcastle will use to generate the documentation. Right-click on Documentation Sources in the Project Explorer and choose "Add Documentation Source...". Navigate to Guy.dll and select it. SHFB should also find the XML file—it should add both Guy.dll and Guy.xml to the documentation sources:
If you are building documentation for an assembly that references other assemblies, you can add them using the References node in the Project Explorer. You add them just like you add references in Visual Studio.
Next, you'll want to select the output format. By default, Sandcastle generates an HtmlHelp CHM file. Use the HelpFileFormat dropdown to uncheck HtmlHelp1 and add Website:
You can also use the HtmlHelp1 option to create an HTML Help (*.chm) file. But before you can use it, you need to install the Html Help 1.x SDK. See the HTML Help MSDN page for more information and a download link.
Click the Save All toolbar button to save Guy.shfbproj. Your Sandcastle Help File Builder project is now ready.
You're now ready to run Sandcastle. Choose Documentation >> Build Documentation from the menu to run Sandcastle. You should see Sandcastle run in the Build Output tab:
Uh-oh—it looks like you got an error!
SHFB: Error BE0033: No APIs found to document. See error topic in help file for details.
Remember how I said earlier that your assembly has to have at least one namespace with at least one public class in it? The Guy.dll assembly doesn't have one.
Luckily, it's an easy fix. Open up Guy.cs in Notepad and make the following changes.You'll use the namespace
keyword to put the Guy class in a namespace called GuyTest
, and you'll use the public
keyword to make the Guy class public—and make sure that you add a closing bracket at the bottom! Here's what it should look like (the new text is in bold
):
using System;
namespace GuyTest {
/// <summary>
... existing Guy class ...
/// A guy with a name, age and a wallet full of bucks
/// </summary>
public class Guy
{
}
}
Now that your Guy class is public and in the GuyTest namespace, you can recompile the assembly. Run CSC again to recompile Guy.dll. This should overwrite the old Guy.dll and Guy.xml files.
This time, CSC should give you an warning about a missing XML comment, but it will run:
C:\temp\Guy>%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library /doc:Guy.xml Guy.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.
Guy.cs(47,29): warning CS1591: Missing XML comment for publicly
visible type or member 'GuyTest.Guy.ToString()'
We'll fix that in a minute. But first, use Documentation >> Build Project to run Sandcastle again. This time the build should complete successfully:
Congratulations—you have now successfully built HTML API documentation! Open up the file Help\Index.html
in Internet Explorer. You should get a warning message at the top of the page:
Click on it and select "Allow blocked content..." from the menu. Once you do, you should see your newly generated HTML help!
Fix [Missing <summary> documentation]
Sandcastle problems
You might have noticed that the HTML help page has the title, A Sandcastle Documented Class Library. Fix this by going back to the Project Properties page and changing the Help Title property. Make sure you save the SHFB project file afterwards.
Next, remember that warning CSC gave you about a missing XML comment?
Guy.cs(47,29): warning CS1591: Missing XML comment for publicly visible type or member 'GuyTest.Guy.ToString()'
Go to to the HTML help in Internet Explorer and navigate down to GuyTest Namespace >> Guy Class >> Guy Methods >> ToString Method. You should see this:
[Missing <summary> documentation for "M:GuyTest.Guy.ToString"]
That's what Sandcastle generates when it can't find documentation. You can fix this by adding an XML comment for the ToString() method. Add this comment above the ToString() method:
/// <summary>
/// The ToString() method returns the guy's name, age and cash
/// </summary>
public override string ToString() {
return String.Format("{0} is {1} years old and has {2} bucks", Name, Age, Cash);
}
Add an AssemblyInfo.cs file to set assembly attributes
Finally, click on any of the Guy members. You should see a line that looks like this:
Assembly: Guy (in Guy.dll) Version: 0.0.0.0
You can change that version number by creating a file called AssemblyInfo. It's exactly the same file that Visual Studio typically creates in the Properties folder. Here's one for the Guy class—I created it using Visual Studio by creating a new project, but you can just paste it into Notepad and save it as AssemblyInfo.cs:
AssemblyInfo.cs:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Guy Assembly")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("O'Reilly Media, Inc.")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("Copyright © 2010 O'Reilly Media")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("150a99f2-01b4-4869-8be2-58df41da0bb2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Now you can use CSC to recompile the program, this time adding AssemblyInfo.cs to the end of the command line. Here's what the command should look like:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library /doc:Guy.xml Guy.cs AssemblyInfo.cs
If you right-click on the DLL in Explorer and choose Properties, you can see the new version number, title, company, and copyright on the Details tab.
Now click on the root node ("GuyTest Namespace") in the tree. Notice how it also has a similar error:
[Missing
documentation for "N:GuyTest"]
XML comments don't work with namespaces. But don't take my word for it - try adding a <summary> comment to the namespace and rebuild your code. You'll get a warning like this:
warning CS1587: XML comment is not placed on a valid language element
Your DLL and XML files will be generated just like before, but the XML file won't contain a namespace summary.
Luckily, this is something that you can easily take care of in Sandcastle. Go back to the Project Properties page and click on the "NamespaceSummaries" property in the Comments section. An ellipsis (...) button should appear—click it. The Namespace Summaries window should appear. Click on the GuyTest namespace in the "Checked namespaces" box to select it, and make sure it's checked, along with the "(global)" checkbox. Then make sure Guy is selected in the "Selected namespace appears in" box to the right. Then enter a summary in the large box on the bottom.
Close the Namespace Summaries window. The NamespaceSummaries property should now read: 1 with summary, 0 excluded.
Click the Save All toolbar button and rebuild the documentation. When you reload it in Internet Explorer, you should see the summaries for the namespace and the ToString() method.
Use MSBuild to run Sandcastle from the command line
Once you've got your SHFB project (*.shfbproj) file working, you can build it from the command line using MSBuild, the build system for Visual Studio. Just like CSC, it's installed with the .NET Framework. And all you need to do to use it to build the Guy documentation is run the following command:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe Guy.shfbproj
Hold on—did you get the following error?
error MSB4019: The imported project "C:\SandcastleHelpFileBuilder.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
If you did, make sure the DXROOT, SHFBROOT, and LANGUAGE variables are set. If you don't set the SHFBROOT variable, you'll get that message. And if you don't set the DXROOT variable, SHFB won't be able to find Sandcastle. So you may need to execute the three set
commands again (the same ones you ran before running SHFB) if those variables aren't already set.
Here's what it looked like when I ran it:
And it generated exactly the same documentation. This is extremely useful for integrating your documentation into a continuous build.
Did get a warning (SHFB : warning BHT0001
)? If you did, this is a known problem with some versions of SHFB. You might be able to suppress the warning by using MSBuild 3.5 instead of 4.0.x. In most cases, SHFB and Sandcastle still build documentation just fine, even with that warning. For more information, see this thread on the SHFB Codeplex site.
Using Sandcastle Help File Builder with a Visual Studio project
Sandcastle Help File Builder can also use a C# project file (*.csproj) as a documentation source. Here's how to take your existing Guy.cs and AssemblyInfo.cs file and add them to a new Class Library project in Visual Studio, and then build documentation from that project with Sandcastle Help File Builder.
First, create a new Visual Studio project and add Guy.cs and AssemblyInfo.cs to it:
- Start Visual Studio and create a new Class Library project called GuyTest(GuyTest.csproj).
- Delete the Class1.cs file that Visual Studio automatically added for you.
- Right-click on GuyTest in the Solution Explorer and add an existing item to add your project. Navigate to the Guy.cs file and add it.
- Expand the Properties folder in the Solution Explorer and delete the AssemblyInfo.cs file.
- Add another existing item to your project—this time, navigate to AssemblyInfo.cs. Once it's added, drag it into the Properties folder.
There's one more thing you need to do. Right-click on GuyTest in the Solution Explorer and choose Properties from the menu to bring up the Project Properties page. Click on the Build tab and check the XML Documentation file checkbox. Specify Guy.xml as the filename.
Click the Save All toolbar button to save your project. This project now builds the same Guy.dll and Guy.xml files that you built earlier with CSC. Not only that, but if you want, you can compile it from the command prompt using MSBuild—just pass it GuyTest.csproj as a parameter.
Now go back to Sandcastle Help File Builder. Right-click on Guy.dll in the Documentation Sources and choose Remove from the menu. Then do the same for Guy.xml.
Finally, add GuyTest.csproj to the Documentation Sources. It should be in the folder that Visual Studio created for you. Click the Save All button on the toolbar to save GuyTest.shfbproj.
Now you can re-run Sandcastle, either using Sandcastle Help File Builder or MSBuild. This time, it will generate the same documentation, but it will do it using the .csproj file instead of the DLL and XML files you generated with CSC.
First, you need to build the DLL. You can do it in Visual Studio—or, if you want, you can use MSBuild. Here's the command line I used, passing MSBuild the full path to my GuyTest.csproj file. Note: Make sure you specify the correct path! And enclose it in quotes if there are any spaces.
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "C:\Users\andrew\Documents\Visual Studio 2010\Projects\GuyTest\GuyTest\GuyTest.csproj"
Then I used MSBuild to build GuyTest.shfbproj again. It built the same HTML documentation, but this time it used the C# project file as the source.
Andrew Stellman is the author of Head First C# and other books from O'Reilly. You can read more from Andrew at Building Better Software.