Click here to Skip to main content
15,306,017 members
Articles / Programming Languages / C#
Posted 23 May 2007


69 bookmarked

ImmDoc .NET - a tool for generating HTML documentation

Rate me:
Please Sign up or sign in to vote.
5.00/5 (33 votes)
27 Jun 20076 min read
ImmDoc .NET is a command-line utility for generating HTML documentation from a set of .NET assemblies and XML files created by the compiler.


Do you remember Visual Studio 2003 and its nice feature of generating HTML documentation for your projects? I bet many of you do and just like I do, you miss it now because unfortunately in Visual Studio 2005 it's no longer present.

Recently, I needed such functionality to document a .NET library I've been developing and just couldn't find the right tool to do the job. I'm aware of the existence of NDoc, but as far as I know it's quite dormant these days and it lacks support for .NET Framework 2.0. So I decided to spare some time to develop such a tool by myself, hoping that I would learn something new and that it'll be useful not only for me, but also for other programmers out there.

Below I put the list of topics that I had to broaden my knowledge on to complete the project, so you know what you can learn by analyzing the provided source code:

  • reflection mechanisms
  • subtleties of C# and MSIL
  • regular expressions
  • syntax of the XML comment files generated by the compiler
  • how to read XML files and programmatically validate them against a schema definition
  • embedded resources


Before I give you more technical details about ImmDoc .NET, you may want to visit this page and see the example output generated by this tool. That is, documentation of three arbitrarily chosen assemblies from .NET Framework: System.Runtime.Remoting, System.Security and System.Transactions.


Currently, there's only command-line interface available for ImmDoc .NET. One of the reasons for this is the fact that creating GUI requires some time. However, thanks to this approach one can easily use the program from batch scripts or tools supporting the build process, such as NAnt.

The usage of ImmDoc .NET is pretty easy and straightforward. You can put all of your assemblies and XML comment files in one folder along with the ImmDoc .NET executable. Then run the program and, after some processing, you'll get a doc folder containing the generated documentation. You can also explicitly give the names of the files you want ImmDoc .NET to process and you can use a few options, which I list below:

  • -pn, -ProjectName:STRING - use this switch if you want to give your documentation project a meaningful name
  • -ex, -Exclude:FILE - if you don't explicitly give the file names, you can use this switch to exclude particular files from processing
  • -od, -OutputDirectory:DIR - use this switch to specify the name of the directory where you want to have your documentation generated
  • -fd, -ForceDelete - ImmDoc .NET will not delete the output directory if it already exists, unless you use this switch
  • -vl, -VerboseLevel:LEVEL - you can set various levels of verbosity, i.e. the greater the level is, the more output from the program you'll get; LEVEL can be from 0 (no output) to 3 (full output)

There is also a feature which needs explicit mention. Because it's not possible to put XML comments on namespaces and because you can document multiple assemblies together, ImmDoc .NET provides a way to add additional comments. To do this, you have to create an XML file with the .docs extension. The syntax of this file is very simple, but note that it'll be validated against a schema, namely AdditionalDocumentation.xsd, which you can find in the ZIP archive with the source code. After you've created such a file, all you have to do is put it in one folder with your assemblies and XML comment files that you want to process or just explicitly give its name as an argument to the program. Below is the example:

<?xml version="1.0" encoding="utf-8"?>
    <assembly name="SomeAssembly">
            Description of the assembly goes here.
        <namespace name="Some.Namespace">
                Description of the namespace goes here.

Project architecture and design

ImmDoc .NET comprises two assemblies that are merged at the end by the ILMerge tool, which is why there's only one EXE file. These are ImmDocNetLib, which actually does the whole job of analyzing assemblies and XML comment files, and ImmDocNet, which is a console application that uses ImmDocNetLib and provides the interface for the user.

As I've already said, ImmDocNetLib has two main responsibilities: analysis of given assemblies and generating the documentation. Let's have a closer look at the first task, which in principle involves using reflection to obtain detailed information about assemblies and the modules they contain.

You'll find the most important classes in the Imm.ImmDocNetLib.MyReflection.MetaClasses namespace. These classes are lightweight and more or less exact equivalents of classes from the System.Reflection namespace. Essentially, almost all of them inherit from the MetaClass class which, among other things, contains properties like Name, Summary and Remarks. Other classes add specific details concerning entities they represent, e.g.. MyMethodInfo holds information about return type and parameters. Such information is often represented in ImmDoc .NET by other classes that inherit from MetaClass like, for example, MyParameterInfo, MyFieldInfo, etc.

So in the first step of the processing, information obtained using ordinary reflection mechanisms is combined with comments extracted from XML comment files to form an internal representation of given assemblies. Below is the UML diagram, which will hopefully give you some overview of this representation. To avoid clutter, not all classes are included:

Internal structure

After collecting all of the needed information, it's finally time to start generating some documentation. Relevant classes are contained in the Imm.ImmDocNetLib.Documenters namespace. We have there a simple abstract class named Documenter, from which we can derive other classes responsible for generating documentation in whatever format we like. I've implemented the HTMLDocumenter class, which creates a set of HTML, CSS and JavaScript files. Together, these constitute a nice MSDN-like documentation of given assemblies.

HTMLDocumenter is a rather big class, so in order to reuse some functionality one would probably want to do some high-level refactoring before implementing one's own documenter. To give you a general overview of the responsibilities of HTMLDocumenter, I've created a simple UML diagram that lists example methods implemented by this class.

Documenters Namespace

Here are short descriptions of the above methods:

bool GenerateDocumentation(string outputDirectory, 
            DocumentationGenerationOptions options)

This initiates the process of generating documentation. It invokes such methods as PrepareOutputDirectory(), GenerateMainIndex(), ExtractStyleSheets(), ProcessAssemblies(), GenerateTableOfContents(), etc.

void CreateInvokableMembersOverloadsIndex
    (MyInvokableMembersOverloadsInfo myInvokableMembersOverloadsInfo, 
    MyClassInfo declaringType, string dirName)

This method creates an HTML page that will contain an index of all overloads of a particular method or constructor.

string CreateNamespaceMemberSyntaxString(MyClassInfo namespaceMember)

This method is responsible for creating a type declaration string. Such a string comprises, for example, a visibility modifier, base class, implemented interfaces, constraints on generic parameters, etc.

void ExtractBinaryResourceToFile(string resourceName, string fileName)

There are couple of graphics used in the generated pages. This method is used to extract a specified embedded resource to a physical file.

string ProcessComment(string contents)

This method processes every comment found in an XML file in order to replace such tags as <code>, <c>, <see> and so on with appropriate HTML tags.

void WriteIndexHeader(StreamWriter sw, string pageTitle, 
                string[] sectionsNamesAndIndices)

This method writes a common HTML header used by almost all generated pages.

string ResolveLink(MetaClass metaClass)

For the generated documentation to be usable, it is necessary to provide some navigation between pages. This method aids with the task of creating hyperlinks, for example, to the particular member of a class.


I hope that someone will find ImmDoc .NET useful; I know I do. I'm waiting for some feedback and if there is some interest I'll continue to develop this project. It still lacks some minor features and, after all, a user-friendly front-end would be a nice thing to have. So if you have some suggestions, questions or maybe you've found a bug I'd be more than glad to "hear" from you. My e-mail is: [admin at immortal dot pl]. You may also want to visit the ImmDoc .NET Homepage. This is the place where you'll most probably find the latest releases of the project and news concerning it.


  • 23 May, 2007 -- Original version posted
  • 21 June, 2007 -- Downloads updated
  • 27 June, 2007 -- Downloads updated


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Marek Stoj
Poland Poland
I'm studying computer science at the University of Wroclaw in Poland. Currently I'm on a one-semester scholarship at the Dresden University of Technology (Computational Engineering program). Main areas of my interests are: game programming (mostly for mobile platforms), .NET, artificial intelligence (in particular natural language processing), software engineering (in particular object-oriented design and analysis, aspect-oriented programming and component-based software engineering).

Comments and Discussions

GeneralNew home for ImmDoc.NET Pin
Marek Stoj25-Jul-09 4:00
MemberMarek Stoj25-Jul-09 4:00 not working as document Pin
ElDopa16-Apr-09 4:22
MemberElDopa16-Apr-09 4:22 
Quote: "... To do this, you have to create an XML file with the .docs extension. The syntax of this file is very simple, but note that it'll be validated against a schema, namely AdditionalDocumentation.xsd, which you can find in the ZIP archive with the source code. After you've created such a file, all you have to do is put it in one folder with your assemblies and XML comment files that you want to process or just explicitly give its name as an argument to the program. ..."

That's not how the code in the download packages is. Both the .exe and the src download only process "" correctly, whenever you use a different name it fails. The code line generating this error is:

Program.cs, line 467:

xr = XmlReader.Create("", xrs);

which should be:

xr = XmlReader.Create(fullFileName, xrs);

I recall using this in the past without any problems, but in that case I might have used a version
from the ImmDoc.Net homepage instead of this CodeProject one. Unfortunately, the ImmDoc.Net website seems offline ?
GeneralI really like this tool Pin
spoodygoon30-Aug-08 2:14
Memberspoodygoon30-Aug-08 2:14 
GeneralVery very nice work Pin
Edson Mattos8-Oct-07 17:05
MemberEdson Mattos8-Oct-07 17:05 
QuestionSand castle? Pin
Stephen Brannan27-Jun-07 6:57
MemberStephen Brannan27-Jun-07 6:57 
AnswerRe: Sand castle? Pin
Liam O'Hagan2-Aug-07 14:09
MemberLiam O'Hagan2-Aug-07 14:09 
GeneralSucceeds in filling the vacuum created by Studio 2005 to NDOC Series Pin
Vasudevan Deepak Kumar26-Jun-07 2:43
MemberVasudevan Deepak Kumar26-Jun-07 2:43 
AnswerRe: Succeeds in filling the vacuum created by Studio 2005 to NDOC Series Pin
The Bug28-Jun-07 1:12
MemberThe Bug28-Jun-07 1:12 
NewsInfo about new releases Pin
Marek Stoj26-Jun-07 2:08
MemberMarek Stoj26-Jun-07 2:08 
GeneralAdded CHM support Pin
Marek Stoj25-Jun-07 6:05
MemberMarek Stoj25-Jun-07 6:05 
GeneralRe: Added CHM support Pin
Vasudevan Deepak Kumar26-Jun-07 2:46
MemberVasudevan Deepak Kumar26-Jun-07 2:46 
QuestionWhat's wrong with Sandcastle? Pin
Joe Sonderegger24-Jun-07 19:43
MemberJoe Sonderegger24-Jun-07 19:43 
AnswerRe: What's wrong with Sandcastle? Pin
Stephen Brannan27-Jun-07 6:57
MemberStephen Brannan27-Jun-07 6:57 
AnswerRe: What's wrong with Sandcastle? Pin
CSharper94-Jul-07 22:38
MemberCSharper94-Jul-07 22:38 
QuestionComments are not written in docs... Pin
Tonster10121-Jun-07 9:09
MemberTonster10121-Jun-07 9:09 
AnswerRe: Comments are not written in docs... Pin
Marek Stoj21-Jun-07 9:26
MemberMarek Stoj21-Jun-07 9:26 
GeneralRe: Comments are not written in docs... Pin
Tonster10121-Jun-07 10:29
MemberTonster10121-Jun-07 10:29 
GeneralRe: Comments are not written in docs... Pin
Marek Stoj21-Jun-07 13:04
MemberMarek Stoj21-Jun-07 13:04 
GeneralRe: Comments are not written in docs... Pin
KeithSKTM26-Jun-07 0:34
MemberKeithSKTM26-Jun-07 0:34 
GeneralRe: Comments are not written in docs... Pin
Marek Stoj26-Jun-07 1:57
MemberMarek Stoj26-Jun-07 1:57 
GeneralRe: Comments are not written in docs... Pin
KeithSKTM26-Jun-07 2:23
MemberKeithSKTM26-Jun-07 2:23 
QuestionCHM output? Pin
balazs_hideghety21-Jun-07 3:30
Memberbalazs_hideghety21-Jun-07 3:30 
AnswerRe: CHM output? Pin
Marek Stoj21-Jun-07 3:42
MemberMarek Stoj21-Jun-07 3:42 
GeneralFixed a little bug manifesting in IE 6. Pin
Marek Stoj21-Jun-07 2:56
MemberMarek Stoj21-Jun-07 2:56 
GeneralSource code missing Pin
TBermudez15-Jun-07 10:41
MemberTBermudez15-Jun-07 10:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.