I've recently started catching up with all the blogs that I've wanted to write and have had flagged to write for a long time. This one I have had flagged since 26 January 2016.
I like building .NET libraries and use Ghost Doc all the time to help me generate my documentation.
Using Ghost Doc
Before just jumping in, let's see a little about what Ghost Doc is. First of all, Ghost Doc has a lot of features and I would encourage you to visit their products page to see all of them.
Using the default shortcut of ctrl + shift + D, you can add a basic comment to your code that generally only needs a little repair to make it properly human readable. Take this very basic add method for example:
public static long Add(long number1, long number2)
{
return number1 + number2;
}
Using the Ghost Doc shortcut, I can generate some basic docs that would look like this:
public static long Add(long number1, long number2)
{
return number1 + number2;
}
As you can see, the default comments are very readable, so in this case I'll use that comment as is .
Spell Check
Ghost doc also installs with a spell checker which I love because my spelling is terrible at the best of times. Other spell checkers that I've used in the past in Visual Studio only check obvious things like string literals but Ghost Doc checks a whole lot more for example in variable names.
Note how it splits the casing on the variable to know where each word is and you can correct your spelling with a single click on the mouse . You can configure what you want the spell check to work for in the options menu.
With this extension installed, opening other people's code, you very quickly notice typos that you would normally not .
Generating Documentation with Ghost Doc
This post's primary focus is on how to generate documentation with Ghost Doc, so let's see how that works. First off, you'll need to have Ghost Doc installed obviously . Next, open a cmd window and change directory to the directory where you have a solution with existing XML comments.
Now all you have to do is run the cmd tool, passing in the solution file and a couple of other parameters.
"C:\Program Files (x86)\SubMain\GhostDoc Enterprise\SubMain.GhostDoc.Cmd.exe"
/solution:"BasicCalc.sln" /helpConfiguration:"HelpFile"
/projectconfiguration:"Debug" /consoledetailed
This will generate some output into the console because we specified the /consoledetailed
flag:
Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.
M:\_code\random\BasicCalc>"C:\Program Files
(x86)\SubMain\GhostDoc Enterprise\SubMain.GhostDoc.Cmd.exe" /solution:"BasicCalc.sln"
/helpConfiguration:"HelpFile" /projectconfiguration:"Debug" /consoledetailed
SubMain.GhostDoc.Cmd v5.5.17070
Copyright (c) 2002-2017 SubMain
User: Gordon Beeming
Target framework: 2.0.50727.8784
------ Parsing started: Project: BasicCalc ------
Parsing...
---------------------- Done ----------------------
Parsing complete -- 0 errors
Loading references...
Building Help Documentation...
Collecting member comments for "BasicCalc" project...
Building member comments file for "BasicCalc" project...
Building topic file for "BasicCalc" project...
Building reflection file for "BasicCalc" project...
Building solution topic file...
Building solution reflection file...
Building solution TOC file...
Building preview files...
Info: CopyFromFileComponent: Instantiating component.
Info: CopyFromFileComponent: Loading data file 'Theme\Transforms\skeleton.xml'.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Searching for files that match 'reflection.xml'.
Info: CopyFromIndexComponent: Indexed 8 elements in 1 files.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 1 subcomponents.
Info: IfThenComponent: Instantiating component.
Info: SyntaxComponent: Instantiating component.
Info: SyntaxComponent: Loaded 3 syntax generators.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Searching for files that match 'BasicCalc_comments.xml'.
Info: CopyFromIndexComponent: Searching for files that match '*.xml'.
Info: CopyFromIndexComponent: Indexed 148486 elements in 121 files.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Instantiating component.
Info: ForEachComponent: Loading subcomponents.
Info: IfThenComponent: Instantiating component.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ForEachComponent: Loaded 2 subcomponents.
Info: CopyFromIndexComponent: Instantiating component.
Info: CopyFromIndexComponent: Loaded 0 copy components.
Info: ShowMissingComponent: Instantiating component.
Info: ShowMissingComponent:
[Sandcastle Help File Builder, version 1.9.3.0]
Show Missing Documentation Component. Copyright c 2006-2011, Eric Woodruff, All Rights Reserved
http://SHFB.CodePlex.com
Info: ShowMissingComponent: All Show Missing options are disabled. The component will do nothing.
Info: VersionInfoComponent: Instantiating component.
Info: VersionInfoComponent:
[Sandcastle Help File Builder, version 1.9.3.0]
Version Information Component. Copyright c 2006-2011, Eric Woodruff, All Rights Reserved
http://SHFB.CodePlex.com
Info: CodeBlockComponent: Instantiating component.
Info: CodeBlockComponent:
[Sandcastle Help File Builder, version 1.9.3.0]
Code Block Component. Copyright c 2006-2011, Eric Woodruff, All Rights Reserved.
Portions copyright (c) 2003, Jonathan de Halleux, All rights reserved.
http://SHFB.CodePlex.com
Info: TransformComponent: Instantiating component.
Info: PostTransformComponent: Instantiating component.
Info: PostTransformComponent:
[Sandcastle Help File Builder, version 1.9.3.0]
Post-Transform Component. Copyright c 2006-2011, Eric Woodruff, All Rights Reserved
http://SHFB.CodePlex.com
Info: MultiFormatOutputComponent: Instantiating component.
Info: MultiFormatOutputComponent:
[Sandcastle Help File Builder, version 1.9.3.0]
Multi-Format Output Component. Copyright c 2006-2011, Eric Woodruff, All Rights Reserved
http://SHFB.CodePlex.com
Info: MultiFormatOutputComponent: Loading components for HtmlHelp1 format
Info: SharedContentComponent: Instantiating component.
Info: SharedContentComponent: Searching for files that match 'Theme\content\shared_content.xml'.
Info: SharedContentComponent:
Loading shared content file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\Theme\content\shared_content.xml'.
Info: SharedContentComponent:
Overriding shared content item 'fsharp' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\Theme\content\shared_content.xml'.
Info: SharedContentComponent: Found 1 files in Theme\content\shared_content.xml.
Info: SharedContentComponent:
Searching for files that match 'Theme\content\reference_content.xml'.
Info: SharedContentComponent: Loading shared content file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\Theme\content\reference_content.xml'.
Info: SharedContentComponent: Found 1 files in Theme\content\reference_content.xml.
Info: SharedContentComponent:
Searching for files that match 'shared\content\syntax_content.xml'.
Info: SharedContentComponent: Loading shared content file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\shared\content\syntax_content.xml'.
Info: SharedContentComponent: Found 1 files in shared\content\syntax_content.xml.
Info: SharedContentComponent:
Searching for files that match 'Theme\content\feedback_content.xml'.
Info: SharedContentComponent: Loading shared content file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\Theme\content\feedBack_content.xml'.
Info: SharedContentComponent: Found 1 files in Theme\content\feedback_content.xml.
Info: SharedContentComponent: Searching for files that match 'SharedBuilderContent.xml'.
Info: SharedContentComponent: Loading shared content file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'roottopictitle' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'rootlink' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'runningheadertext' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'locationinformation' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'assemblynameandmodule' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'copycode' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'locale' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\SharedBuilderContent.xml'.
Info: SharedContentComponent: Found 1 files in SharedBuilderContent.xml.
Info: SharedContentComponent:
Searching for files that match 'PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent: Loading shared content file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'header' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'footer' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'fb_alias' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'fb_product' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'fb_body' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'fb_send' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'fb_headerfeedback' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'feedback_alias' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'feedback_product' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent:
Overriding shared content item 'feedback_body' with value in file
'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1\PresentationStyleBuilderContent.xml'.
Info: SharedContentComponent: Found 1 files in PresentationStyleBuilderContent.xml.
Info: SharedContentComponent: Loaded 641 shared content items.
Info: ResolveReferenceLinksComponent2: Instantiating component.
Info: ResolveReferenceLinksComponent2:
Searching directory 'C:\Users\Gordon Beeming\AppData\Local\Temp\SubMain.GhostDoc`1
' for targets files of the form 'reflection.xml'.
Info: ResolveReferenceLinksComponent2: Loaded 47172 reference targets.
Info: SaveComponent: Instantiating component.
Info: BuildAssembler: Building topic N:BasicCalc
Info: BuildAssembler: Building topic T:BasicCalc.Calc
Info: BuildAssembler: Building topic AllMembers.T:BasicCalc.Calc
Info: BuildAssembler: Building topic Methods.T:BasicCalc.Calc
Info: BuildAssembler: Building topic M:BasicCalc.Calc.Add(System.Int64,System.Int64)
Info: BuildAssembler: Building topic M:BasicCalc.Calc.Minus(System.Int64,System.Int64)
Info: BuildAssembler: Building topic M:BasicCalc.Calc.Multiple(System.Int64,System.Int64)
Info: BuildAssembler: Building topic M:BasicCalc.Calc.Divide(System.Int64,System.Int64)
Generating help documentation...
Building HTML help index file...
Compiling HTML help file...
Help folder: M:\_code\random\BasicCalc\Help
Done.
M:\_code\random\BasicCalc>
You will need to install HTML Help Workshop which you can get from Ghost Docs site.
Now that will create a Help folder and inside it a .chm file.
We can open that file and you will notice that all our comments have been formatted nicely into what looks like the old MSDN style documentation.
Ghost Doc generates to other formats as well as you would see on their editions compare page.
We now have a chm that we can distribute with our source .
Adding This To Our CI
Generating docs from your machine is ok but then you have to remember to do it and what's worse is that you'll have to check that file into source control (Emphasis on the Source in source control ) which wouldn't be great. So naturally as Donovan Brown reminds us "anything you can do on a command line you can do in VSTS or TFS" .
I've gone ahead and setup a standard CI build using the built in Visual Studio template.
If we look at the current build artifacts, you will notice that only our class library and pdb is being published.
To add the help file to this, we are going to do a couple steps. First, add Command Line task:
and place it before the Copy Files to: $(build.artifactstagingdirectory) task:
Now we need to update a couple values for the task:
- Set the Tool to "C:\Program Files (x86)\SubMain\GhostDoc Enterprise\SubMain.GhostDoc.Cmd.exe"
- Set Arguments to "/solution:"BasicCalc.sln" /helpConfiguration:"HelpFile" /projectconfiguration:"$(BuildConfiguration)" /consoledetailed"
- Note that we are specifying
$(BuildConfiguration)
as the configuration so docs are generated for the configuration we are specifically building
- Check the Fail on Standard Error checkbox:
Now add a Copy Files task:
and add this below the Command Line task:
and now set:
- Source folder to "$(build.sourcesdirectory)"
- Contents to "**\Help\**"
- Target Folder to "BasicCalc\bin\$(BuildConfiguration)\"
- And Check the Overwrite checkbox
If we click Save and run this build, you will notice that after the build runs, we have our help file in the drop.
We are not guaranteed to always have up to date source documentation with our build outputs.
Conclusion
If you write libraries either for internal or external use using the XML comments, I'd highly recommend you take a look at Ghost Doc as it makes your life really easy. Also, with the very powerful Visual Studio integration, developers will be a lot more productive and really have no excuse not to generate meaningful documentation for your class libraries.
Happy documenting!