Table of contents
Short introduction
From the first versions of Visual Studio .NET, it has been possible to document your classes directly in code and create the standard documentation sections (such as the summary, remarks, parameter descriptions etc) which contain the standard tags. But for us, developers, it was quite inconvenient to fully document our classes and create such long sections as remarks directly in code. The situation is worse in the case when the documentation is created by a technical writer and the code is created by a developer; it is not quite appropriate for them to work with the same source files simultaneously.
Our company also encountered all these problems while working on our first .NET component. We decided to solve them by creating our own tool and gave it a name "DocMounter". DocMounter became a tool to separate the code from the documentation without loss of the conveniences provided by Visual Studio, and even more. Step by step the tool was being improved, and finally it has become an easy-to-use application that can be useful for other developers. The actual version implements many useful features you cannot get from the standard VS XML documentation technique.
CodeProject already contains a post about the first version of our tool (see this article), but we decided to publish a new one regarding the next generation of the tool we have recently released. The tool was practically rewritten in 80% of places and now it is practically a brand new tool (though we tried to keep the visual simple ideology the same), so we thought the tool deserved a new article.
Main features
DocMounter allows you to perform the following tasks:
Enter all the standard sections such as summary, remarks, example, see also, etc for classes and their members through its visual interface.
Add standard XML documentation tags - such as see, code, list, table, etc - through a handy insert tag dialog.
Create additional topics using the same syntax as for the classes and their members (XML documentation syntax).
Manage the nodes of your project, i.e. the structure of the table of contents of the future help file.
View and edit the source of your topics in an editor window that supports syntax highlighting, customizable spell checking and code folding.
Create conceptual topics (which are not related to a particular class or its member) using the same syntax as for the classes and their members.
Generate the standard XML documentation files which can be used in any tool and development environment that supports it (including all versions of Visual Studio .NET).
Generate a single HTML file from all the additional topics. Later this file may be slightly edited and converted into a DOC, RTF, or PDF format and used as a manual.
The internal extensible model of DocMounter allows to integrate external documentation compilers (such as NDoc or SandCastle) to produce the required output documentation.
Simplicity, Simplicity and Simplicity once more
There are few open-source projects to build documentation, such as outdated NDoc and the modern SandCastle documentation compiler, but if you ever tried to use them you know how difficult to make them working for your practical needs. When we designed DocMounter, the simplicity was one of the main key features of the product, and now we have a wonderful tool you can use to build help solutions from the first minutes after deployment with one mouse click.
Despite its simplicity, DocMounter has the complete set of tools you can use to build full-featured XML documentation and help files. As we said, we are using it widely in our company to document our .NET products. Many developers throughout the world also found this tool very useful for their projects.
DocMounter 2 and Sandcastle
This version of DocMounter uses a free open-source documentation compiler named Sandcastle which is used by the Microsoft team to create the MSDN library. This means that you will get the same look-and-feel HxS documentation like in MSDN used by Microsoft since the VS 2005 release. To find out more about Sandcatsle, visit this home page of the project: http://sandcastle.codeplex.com/.
Sandcastle is downloaded and configured separately as described in the manual, but our DocMounter package also contains small enhancements and corrections to the original Sandcastle installation to have better functionality and look in some places. All these enhancements are applied by DocMounter automatically during the build process, so you do not need to do something by hands for that.
Installation and system requirements
DocMounter is distributed as a portable exe application built with the .NET Framework 4.0, but to have the ability to build and view your HxS solutions, you need to install some Microsoft tools. These are utilities like HxReg.exe to register help namespaces and HxComp used to compile your HTMLs into HxS help solutions. They are included into the VS 2005/2008 SDK, and you need to install it to use all features of DocMounter as well.
Before you use DocMounter, please, read carefully the "Installation and System Requirements" section in the supplied DocMounter Manual PDF document. It is a comprehensive guide that explains what external tools DocMounter needs, where to get them, and how to install and configure the tools.
Easy start
To document your .NET libraries, create a new project using the File\New project menu command. An open file dialog will be displayed – select the required assemblies in it. After you select one or several assemblies and click the "Open" button, the project will be created. You'll see that the topic tree contains all namespaces defined in your assemblies. Your project is ready for work – you can expand the nodes, select members and write descriptions for them in the right big editor pane.
To build your project, just click the "Build & View HxS" button on the toolbar. Your first HxS file will be created and displayed in the Microsoft Document Explorer automatically in a minute. You'll see the complete log of the build process with all possible warnings and error messages in the "Output" pane opened at the bottom of the tool.
Describing classes and their members
DocMounter allows you to describe all the public members of an assembly. After you have loaded a project or created a new one, you can see all the members of the project's assemblies in the member tree located at the left side of the DocMounter main window. When you select a member in this tree, a set of its description sections appears at the right side of the member tree. Each type of member has its own set of sections. Some sections are common across all the types of members (for example, the Summary section is present in every member type). After compiling the help solution, these sections are gathered into a single topic:
You can type any text into a section description, and it will be transmitted to the output topic directly. In addition, this text may contain special tags. These tags allow you to make references to other types and members, create tables and lists, etc. The tags are very similar to the tags used in Visual Studio .NET to document classes and their members. You can find out more about the tags supported by Microsoft in the following article:
Recommended Tags for Documentation Comments (C# Programming Guide)
You can type in tags directly in the topic editor, but that's one more place where DocMounter significantly simplifies your work. Use the handy Insert Tag dialog to do that:
On the left side of the form you can see the complete list of tags which are supported by DocMounter. Some of these tags are not supported by Microsoft XML documentation language because these are special DocMounter tags used to extend the standard XML documentation functionality. When you select a tag from this list, fields reflecting the tag's parameters appear on the right side of the form. Fill in these fields and then press the OK button. The tag will be inserted into the description.
An example
Here is an example. Let's create a summary for the following simple class Class1 (VB.NET syntax):
Public Class Class1
Public Sub Method1()
End Sub
Public Sub GenericMethod(Of T)()
End Sub
End Class
Let's write that the most useful method of our class which does the main work is Method1 and insert a cross-reference link to it, so it would look like the following:
Well, open DocMounter, load the DLL with this simple class for documenting, and click the node that represents the Class1 class. In the right big editor pane type in all the words of our description except the last word "Method1". To insert a cross-reference link to Method1, open the Insert Tag dialog and double-click this member to insert a reference link to it:
It will look like what we see on the following screenshot:
That's enough. Click "Build & View HxS". In a minute we have the desired result:
That's all. Even no need to learn special tags from the MS XML documentation tag set or Sandcastle's MAML language. And pay attention to the fact that you practically type in your description as is - in those specific languages you would need, for example, to use the <para> tags to create paragraphs, and it would give us less attractive look of our text. MAML also requires to wrap your useful user text into an XML document of a special predefined structure, but in DocMounter you work only with your custom descriptions.
Creating and managing conceptual topics
In addition to member descriptions, DocMounter allows you to create so-called conceptual topics which are not related to a specific member. The contents of these topics are not included in the complete XML and XML with summaries, but these topics are included into the help solution. Generally these topics are used to describe the main ideas and concepts of your products.
To create a conceptual topic, use the corresponding command from the Node menu or the context menu of the project topic tree. Later you can rename your topics and reorder them. When you reorder conceptual topics, you can also change their hierarchy.
When you edit the contents of your conceptual topics, you use the same set of DocMounter tags as you use to document your member topics. This is yet another place where DocMounter helps you. Such tools as Sandcastle require to use another language for that (MAML in the case of Sandcastle), but in DocMounter you use the same Insert Tag dialog and even copy prepared parts of topic contents from member topics to conceptual topics, and vice versa.
Used code technologies
This complex tool uses tens of .NET technologies inside. These are manipulations with XML documents on the disk and in memory (including XSLT transformations and XPath queries), threading (when building help solutions - they are built in a separate thread and the build process can be stopped), object-oriented approach to work with project nodes, etc.
If you download the source code of this tool and examine it, you'll find a lot of samples for many .NET techniques. In any case, we would like to highlight a couple of interesting internal approaches in this article below.
Help compiler as a plug-in
DocMounter 1.x used NDoc as its help compiler, Sandcastle is the compiler for this DocMounter v2. But these tools aren't hard-coded into the DocMounter code. In fact, we attach an external help compiler to the interface part enough easily due to the IHelpBuilder interface. Here are the main components of this interface:
public interface IHelpBuilder
{
void BuildHelp(
string[,] assemblyFiles,
string outputDirPath,
string mediaDirPath,
string helpNamespace,
string name,
string title,
string companyName,
string version,
string feedbackEmail,
string docSetList,
ConceptualTopic[] conceptualTopics,
string conceptualTopicXmlsDirPath,
ProcessStepDelegate processStepCallback,
Func<bool /> shouldStopCallback);
void ViewResult(string outputDirPath, string name, string helpNamespace);
bool CanViewResult(string outputDirPath, string name);
}
All you need to do is to implement IHelpBuilder in an DLL, and after that it can be used as a plug-in for DocMounter to compile your projects.
Building project in a separate cancellable thread
All long-term build processes of DocMounter are executed in a separate thread so they can be interrupted by the user using the interface elements. See how we launch the HxS build process:
ProjExecuteInBkThread(new MethodInvoker(ProjBuildHxSBkThread), viewHxSAfterBuild);
And this is the same for the Build Xml Summaries interface command:
ProjExecuteInBkThread(new MethodInvoker(ProjBuildXmlSummariesBkThread), false);
As you can see, the control is passed to the ProjExecuteInBkThread method:
private void ProjExecuteInBkThread(MethodInvoker mehtodToExecuteInBkThread, bool viewHxSAfterBuild)
{
#region Check the arguments
if (mehtodToExecuteInBkThread == null)
new ArgumentNullException("mehtodToExecuteInBkThread");
#endregion
fMehtodToExecuteInBkThread = mehtodToExecuteInBkThread;
fViewHxSAfterBuild = viewHxSAfterBuild;
BuildDisableAllControlsExceptOutput();
StartProcessingOutput();
AdjustStopBuildControls(true);
Thread myThread = new Thread(new ThreadStart(ProjExecutionThreadProc));
myThread.IsBackground = true;
myThread.Start();
}
The main work of the thread is done in ProjExecutionThreadProc:
private void ProjExecutionThreadProc()
{
#if !DEBUG
try
{
#endif
lock (this)
{
fExecutionWasAborted = false;
}
if (fMehtodToExecuteInBkThread != null)
fMehtodToExecuteInBkThread();
lock (this)
{
if (fExecutionWasAborted)
MessagesManager.ShowError(this, "Execution was aborted.");
}
#if !DEBUG
}
catch (Exception ex)
{
MessagesManager.ShowError(this, "Unable to perform operation: " + ex.Message);
}
finally
{
#endif
Invoke(new MethodInvoker(BuildEnableAllControls));
Invoke(new Action<bool />(AdjustStopBuildControls), false);
Invoke(new MethodInvoker(AdjustInsertTagControls));
Invoke(new MethodInvoker(AdjustHxSControls));
if (fViewHxSAfterBuild)
Invoke(new MethodInvoker(ProjViewHxS));
#if !DEBUG
}
#endif
}
This is the "heart" of our threading model. It allows us (1) to launch any build process, (2) to interrupt it if required and (3) to catch unforeseen bugs so the whole tool remains stable and does not crash. Note that the last thing works only in the release version - we still have the ability to stop on an exception in the debugger while developing the tool in the VS IDE. If we didn't use the conditional compilation DEBUG constant, we would get a general user-friendly (but not developer-friendly) error message while debugging instead of highlighting the statement which caused the exception directly in the IDE.
This ideology can be used with any new build process we can invent and incorporate into DocMounter - now we will concentrate only on the core functionality of the new build process.
Resume: Main benefits of DocMounter
Let's list all the main benefits of the tool after this short introductory article so you'll get the general feeling of what this tool can do and how it can save your time.
The most important benefit of DocMounter is that your code and its description are in different places, so your code isn't bloated because of documentation in your source files (what you get in Visual Studio). This also allows two different people to work on the product development and its documentation at the same time independently (the developer and technical writer).
Visual Studio does not allow you to create conceptual documentation as you can only document members in the source code files, but in DocMounter you can create this type of help topics.
DocMounter allows you to build not only an interactive HxS file with a tree structure of conceptual topics, but also a printable manual in which all the conceptual topics are placed one-by-one.
DocMounter produces the documentation of the same look-and-feel as you can see in MSDN.
DocMounter has intuitive user interface and is very simple, but its features covers all the main functions and features you need to write help solutions.
In DocMounter, you write both conceptual and member topics in one unified interface using the same principles and tag set. Instead of writing tags manually, DocMounter provides you with a handy visual "Tag Insert" dialog which saves your time a lot.
Help topics are written practically as plain text in DocMounter's topic editor (you write only the useful contents), and they are automatically compiled into full-featured result help pages which uses the same visual and functional template.
If members you are documenting have been changed (renamed, parameter list was changed, etc), DocMounter automatically updates the project to insert the updated members. All the outdated members aren't removed and can be easily found using a special search command. This allows you to copy the descriptions from the obsolete members into the new ones and remove the obsolete members from the project manually when you no longer need them.
If you already documented your assemblies using the standard Visual Studio approach, DocMounter allows you to easily switch to DocMounter to continue your work in this tool. You can import all your member descriptions from the assemblies' accompanying XML comment files or even from the description attributes stored directly in your assemblies!
Though DocMounter is based on the external Sandcastle help compiler and uses Microsoft's standard XML Documentation and SandCastle MAML languages to build help topics, it adds some cool additional features you couldn't have earlier. Among them are the abilities to insert pictures into member topics and make cross-reference links between member topics and conceptual topics.
And finally, DocMounter is totally free and you can get its full source code also for free!
DocMounter binaries and source code
This article contains links to two packages.
The first of them is the binary files of DocMounter. If you just need the tool, use this package. DocMounter requires the .NET Framework 4.0 and is distributed as a portable application. It also requires Sandcastle and some external tools from the VS SDK, and a comprehensive instruction of how to obtain and install these tools can be found in the DocMounter manual supplied with the product.
The second package is the source code of DocMounter. It is a VS 2010 solution entirely written in C#. It can be used to examine the logic of the tool and modify it for your own needs.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.