Thursday, December 03, 2009

Visual Studio Help Integration Wizard and Continuous Integration

As .Net developers we are constantly using msdn and the Visual Studio help system. One of the most powerful features of Visual Studio is the ability to hit the F1 key on a class, property or method, and have it whisk you away to the correct msdn entry for the item of interest. When using third party libraries, it is great when they are able to provide you with the same ability to search API documentation from within Visual Studio. This is all possible, but I recently discovered, not necessarily trivial, and there is a really big gotcha if you want to add it to your Continuous Integration process.

To start with you need to ensure that all developers of your API are meticulous about putting XML Summary comments on ALL public facing entities. This is a good practice whether or not you intend to distribute the API.

The second step is to use a tool like sandcastle to build compile the xml comments into a usable format. Sandcastle has a number of different outputs including the classic .chm (Compressed html) output that is easy to read and can be distributed with your project, however, if visual studio integration is what you are really after, then you need the Html2 help output (*.hxs). As there are a lot of different settings for sandcastle, it is good to use the SandCastle Help File Builder that provides a nice settings based interface as well as a command line utility to aid you in building your help files.

The third step is to create an installation package (.msi or .msm) to distribute your documentation to the millions of developers who will be using your API to write the next killer application. There are a few ways of achieving this, to do this from scratch you could follow these intructions, however, in the Visual Studio 2008 SDK, there is a project type called the Help Integration Wizard that attempts to automate this process for you. This very simple project template works great right up to the point where you try to integrate it into your Continuous Integration Process.

The first problem is that the solution created contains 2 vdproj files, which means that you can’t build them with MSBuild, and are forced to pollute your build server with Visual Studio and compile it using the devenv command line. However, even after you have taken this hit, the pain doesn’t stop there.

The reason is because of 2 files that are included surreptitiously in the project path but not added to the solution. The executable FixRegTables.exe, and a merge module called MSHelp2_RegTables__RTL_---_---.msm get added to the CollectionFiles folder for the merge module project that is created. If you fail to check these in to your source control solution, your CI build will break with an error about a post build step. However, if you do add them to your source control repository, then chances are when you perform a “Get Latest” operation, these files may well be marked as “Read Only” as this is standard practice for many source control systems to ensure that source files are not modified during a build. In this case, the build will work as expected and produce an msi file, however, the resultant msi file will not install anything when run. The issue is that the Post Build step mentioned above needs to modify the merge module.

The solution is to either check the 2 files in to your source control system, and make the merge module writable as part of a pre build step, or to copy the two files from their location in the visual studio sdk into the Collection Files folder as a prebuild step.


  1. Anonymous6:59 pm

    Thanks, this note saved me a bunch of time. I had the same problem, but was a long way from regonizing it for what it was. Your post described it perfectly. To solve it, I chose to keep the .msm file out of source control, and copy it from a VS2008SDK directory, in the pre-build step inside the .vdproj.

    Thnks again.

  2. You save me too, thanks!

  3. In my case there is third file not added to solution too: IntegrationWizard.xml ... and this file is not from SDK, so be careful :)