November 23, 2012

Visual Studio Settings Switcher

I just published the first release of my Settings Switcher extension for Visual Studio 2012 on CodePlex.

Yesterday, I was looking for a quick solution to switch between Visual Studio settings files (.vssettings) without using the Tools > Import and Export Settings… dialog.  The dialog’s great, but it’s a bit slow to use a wizard every time I want to switch settings.  Sometimes I like to jump back and forth between different solutions quickly during the day, like when I’m working on various open source projects with different code formatting requirements.  I wanted a quicker way to load settings after opening a solution.

I found this blog post, which had a link to a tip on Sara Ford’s blog showing how easy it is to create a command button in the IDE to switch between settings by writing a simple macro.

Unfortunately, Visual Studio 2012 doesn’t support macros.

So I decided to create a Visual Studio extension.  The original premise was simply to show a drop-down list containing all of the .vssettings files and when one is selected those settings are applied.  That turned out to be a useful feature of the extension; however, while I was developing it I realized that I could add a few more useful features.  For example, I added a button to format every code file in the solution according to the currently selected settings.

But the primary feature, IMO, is that when you close a solution or exit Visual Studio, the extension saves a reference to the current settings file in the solution’s user options file (.suo).  The next time that you open that solution, the associated settings are automatically applied by the extension.  “Automate everything” is my motto :)

This extension should be useful to open source developers.  Typically we work on projects across multiple teams, with different code formatting requirements.  The next time you fork a project you can simply open the solution, edit your settings in the normal Tools > Options… dialog to meet the requirements of the team, then export the settings to a new file using the Export Current Settings button on the Settings Switcher toolbar provided by the extension.  And that’s it!  Every time you open that particular solution, its associated settings are applied automatically.

Project coordinators should also consider checking in a .vssettings file to their repositories.  This will make it easier for interested developers to set up their environment for working on your project.  A developer would simply need to copy the .vssettings file that you provided to the directory that Visual Studio uses to export settings files on their system (Tools > Options > Environment > Import and Export Settings).  Then follow the instructions above to associate the settings with the solution.

I’ve got some additional features that I plan on adding in the future, time permitting.  Some of them are very community-oriented.  We’ll see how that goes.

Feedback is appreciated.  Feel free to request a feature, report a bug or start a discussion.


June 06, 2008

Visual Studio Gallery Updated

It appears that Microsoft has improved the Visual Studio Gallery by adding the ability for users to rate and review products.  The interface was jazzed up a bit as well.  Nice work MS - the original gallery was more like a project dump but the new release is community-oriented, which I think people will appreciate.

DocProject has been in the top 10 most visited projects since the VS Gallery went live (it was in the top 3 for quite a while too), which just goes to show you how important documentation is to developers when a tool such as DocProject is more interesting than tools that aid in development.  This certainly motivates me to continue working on it for VS 2008 :)

I'd like your feedback so please drop by and write a review if you can find the time.  Thanks!

February 28, 2008

DocProject in the Visual Studio Gallery

Microsoft's Visual Studio Gallery was announced to the public today.  It provides a one-stop-shop for Visual Studio add-ins, packages, item and project templates, macros, controls, coffee makers, toasters, etc.  I think it's a great idea.  Google can only help so much here (have you tried searching for "visual studio add-ins"? ;)

Anyone can register their free or paid products, so if you've got one, let the world know!

I've added DocProject under the Build, Documentation and Web categories.  It has its own little HTML-formatted corner of the site too, which is a cool feature I think.  Take a look at it here.  It already has over 150 unique views!

Currently, the site does not host products so I simply link back to CodePlex (although I love CodePlex so I have no intention of leaving anytime soon).

From my few short discussions with the site's program manager, Anthony, I'd say that they have some good ideas to work with for the future.  Features that'll make locating products and adding new products easier.  So remember to look back occasionally for updates in the next few months.

February 13, 2008

Sandcastle Build Component Templates 1.1 Released

The Sandcastle Build Component Templates 1.1 release provides two C# Item Templates that you can use to easily create custom Sandcastle Build Components in Visual Studio 2005 and Visual Studio 2008.

In this blog post I intend to provide some details about the templates, with more focus on hosted components and DocProject's APIInstructions for template installation and usage can be found here.

Basic Sandcastle Build Component Item Template

The Basic Sandcastle Build Component item template is a multi-file Visual Studio Item Template, written in C#, that provides a working example of a custom build component that can be used for command-line builds or with editor support in automation tools such as DocProject and the Sandcastle Help File Builder.  It comes with a built-in graphical editor and a dynamic sub property for the DocProject Properties window, which can be shown by expanding the component in a build component stack (for more information about the stack properties, see How To Use Third-Party Sandcastle Components in DocProject).

Hosted Sandcastle Build Component Item Template

The Hosted Sandcastle Build Component item template is the same as the basic template, but it also provides direct access and a working example of how to gather information from DocProject's API, thus DocProject is required in order to compile the build components that are created based on this template.  Although, DocProject isn't actually required to use the components if you provide a fall-back initialization path.

Initialization Paths

The template's Configuration class provides two initialization paths, one of which is a fall-back that's automatically invoked if the DocProject host API is not detected.

Note: The host API is never available during builds - it's only available when the component's editor is displayed.

Fall-back initialization works since the template depends upon just-in-time (JIT) compilation.  If you properly encapsulate the use of host interfaces, as the template does out-of-the-box, then you can control the initialization path of the component's Configuration class.

The template's Host class is used to encapsulate host interfaces and services, and it provides a way to safely check, at runtime, whether a particular host is reachable.  Support for DocProject's host API is built-in to the template.  All other hosts will use the fall-back initialization path automatically unless you add support for them to the Host and Configuration classes.  The only requirement is that the host invokes your component's editor by calling its EditValue method and passes in an IServiceProvider implementation that can be used to obtain a reference to one or more of the host's services.  (On a side note, the value argument should be set to a System.Xml.XPath.IXPathNavigable implementation that's positioned on the outer XML of the component's configuration, which includes the <component> element itself.)

Modifying Project Options

The template gathers read-only data as an example and does not actually modify any build settings or project options at runtime.  If you want your component implementation to write to the API, then make sure there's a clear relationship between your component and the changes that it's making.

For example, a proprietary AuthorBuildComponent changing the value of the Generate root API topic setting when edited will probably not be obvious to end-users.  But it might be appropriate for the same component editor to add external sources if, for example, it were to provide a way for an end-user to create a list of associations between sources and author names, much like the Version management dialog does with version information.   In this case, the component's editor could save the input-to-author mappings as its inner XML configuration data and add the external sources as a convenience for the user.

Hosted Components as Plug-Ins

Hosted build components are not meant to be a plug-in mechanism for DocProject, per se, but instead are a plug-in mechanism for Sandcastle.  DocProject's API is exposed merely to provide a more user-friendly and integrated experience when editing Sandcastle build components in DocProject.

If you want to create a true DocProject plug-in, then create a custom build engine provider or a build process component, which can provide control over all aspects of DocProject, including the entire build process, engine settings, project options, tool bars, tool windows, menus, custom wizard steps in the New Project Wizard, etc.

DocProject's API for Hosted Components

With the recent release of DocProject 1.10.0 RC, a new interface was added that would provide build components access to DocProject's API, for their graphical editors.  The API can be used to gather information about the environment in which the component's editor is being hosted.  The component can then provide automatic configuration and apply appropriate editor defaults, simplifying configuration for end-users while also adhering to the project paradigm that DocProjects and DocSites use to store their settings.

The purpose of the gateway interface, IDocProjectHost is to provide components with access to DocProject-specific interfaces and types for the context in which the component's editor is being hosted.  Here's the interface's definition:

public interface IDocProjectHost
    IDocProject Project { get; }
    BuildSettings Settings { get; }
    DocProjectOptions Options { get; }
    IBuildEngine Engine { get; }
    IEnvironmentHost EnvironmentHost { get; }
    bool RunningInVisualStudio { get; }

The Hosted template gets a reference to an IDocProjectHost implementation through the service provider that's passed to the editor's EditValue method.  If the host is available then the Configuration class's InitializeForDocProject() method is invoked instead of the fall-back Initialize() method (see above for information about initialization paths).

The InitializeForDocProject method uses the types and interfaces exposed through IDocProjectHost to gather information, which it then stores in private fields.  The fields back properties that are used by the template's EditorControl class.  They are typed as nullable primitives, such as System.String and bool?, so if the values are never set then they'll remain null, in which case the EditorControl will substitute them with "Unavailable" for its read-only display.

Developers are free to remove this code (actually, it's recommended) and replace it with appropriate code for gathering information that's required by the component being developed.  However, the same pattern can be used to safely encapsulate data that can be initialized with or without a host API.

Note: The configuration fields must not be typed as host-specific types or interfaces if you want to be able to use your components in other environments, without the host API installed.


With the release of DocProject 1.10.0 RC and the corresponding Hosted Sandcastle Build Component Item Template 1.1, developers can now have seamless integration in DocProject for their custom build components' editors, providing a more robust platform on which to configure and build documentation while potentially simplifying configuration for end-users through automation and inferred default settings.

January 17, 2008

DocProject Roadmap

As you may have already heard, Sandcastle [1] was officially released to the web (RTW) through CodePlex on January 15, 2008.  The license that was chosen is the Microsoft Public License (Ms-PL) [2], but keep an eye on it because it may change [3].  There are still a few unanswered questions that I have [3] about how Microsoft's work on Sandcastle will continue and how it will affect DocProject, but things are looking very positive.

In this blog post I'd like to express a few of my goals and ideas for DocProject and maybe even try to establish some preliminary timeline.  And of course, if you have any thoughts your feedback will be welcomed :)

The End of Phase 1

With the help of community feedback and my propensity for being anti-social in favor of sitting in a dark room, programming, DocProject's long initial development phase is nearing an end.  The next release, which you can read about in my blog (DocProject 1.10.0 RC Preview [4]), brings together a few long-awaited features that will hopefully start to make DocProject into a useful help authoring tool (HAT) [5].  I'm going to try for Monday, January 21st, to release 1.10.0 RC, and I'm hoping that the worst-case scenario will be the following Friday.

From there I expect to deploy only one more Release Candidate that contains various outstanding bug fixes and feature requests and then I'll freeze DocProject's feature set for Visual Studio 2005.  The following deployment, 1.12.0, should therefore be the first DocProject Production release.  Expect that in March, 2008.

Visual Studio 2005 vs. Visual Studio 2008

I expect to have my own licensed copy of VS 2008 Standard edition sometime before the end of February, but until then I've decided that I will not be concentrating on any new deployments for DocProject 2008 Beta, although I'm very excited about using VS 2008 and I'll certainly jump on that bandwagon as soon as I can.

So for now, you can expect development to continue like normal for VS 2005.  But once I start concentrating on VS 2008, I'm probably going to freeze the feature set for VS 2005, distribute the first Production release of DocProject 1.x, and then switch gears for .NET 3.5 and, possibly, VS Package development.  I intended to eventually release DocProject as a true package, hopefully with its own editors and actual project types [6] (i.e., DocProject and DocSite Templates [7] that are recognized by Visual Studio as distinct project types, with their own property pages, etc.).

After DocProject 1.x goes into stabilization (the end of phase 1) I'll certainly provide support for it and help people whenever I can if they have questions about how to modify the source code or how to add additional features themselves.  Although, the only official deployments that you'll see will probably be major releases that fix a large number of bugs.

Well that's my plan anyway because in the last couple of DocProject 2008 releases I've realized that maintaining two versions of the project is almost like double the work; however, since Visual Studio 2008 will allow me to target the .NET 2.0 Framework I may be able to work on both versions of DocProject simultaneously, without much additional effort.  If that's true then hopefully I won't feel the need to freeze the DocProject 1.x feature set.  Although, technically I can't really freeze DocProject's feature set anyway since it's open source ;)

DocProject Documentation

I plan to distribute compiled help for DocProject 1.x that consists of both API reference and conceptual documentation after the first Production release.  I'd say that a week or two should be enough time to author useful, preliminary documentation.  After that I'll probably just add content here and there and deploy whenever I reach certain milestones that I define on the fly.

A .chm will be downloadable from CodePlex and the installer will present you with the option to have DocProject's help content (.HxS) merged with Visual Studio's help.  I'm even considering hosting a DocSite as an online reference and as a great working example of DocProject's and Sandcastle's capabilities.

Phase 2

The next phase will pickup with the development of DocProject 2008, targeting Visual Studio 2008 and the .NET 3.5 Framework.  The timeline will probably start sometime in March, 2008.  From there I hope to deploy on a monthly basis as I've done with DocProject for the past year+ (since December, 2006 as a matter of fact).


Although DocProject, in the next release [4], will provide first-class support for building mixed reference and conceptual documentation, unbounded filtering capabilities, much improved performance and a mostly finalized API, I still see lots of room for improvement.  Namely, in the area of content-based features such as for authoring topics and localization.  Also, here's a few of the outstanding tasks [8] that I'm going to look into for DocProject 2008: 

  • Running DocProject in areas of heightened security (e.g., Vista with UAC enabled).
  • SQL Server full-text search provider for the DocSite templates.
  • Microsoft Word and Adobe PDF output.
  • The ability to annotate comments with developer notes. 
  • Automatic token replacement.
  • Some new DocSite skins, maybe including one that makes judicious use of SilverLight.  (Documentation might start looking better than the software it documents, if I achieve my goal, that is ;)
  • Change control and better support for team scenarios; e.g., the ability to have a server that continuously builds live documentation to keep it up-to-date.
  • The development of a simple community wiki for the DocSite templates, which I guess we can start calling the "DocSite Community Wiki" feature (sure, some might say it's a rip-off of the MSDN Community Content Wiki idea, and I guess they'd be correct ;).  This should be very useful in team scenarios for large, volatile, hosted documentation sets.
  • The ability to register multiple Build Process Components [9] per project, with a management UI as well.  I may even turn the Sandcastle/Deployment [10] engine into a BPC that can be added to any DocProject or DocSite.
  • Other various user-defined tasks (bug fixes and feature requests).

I have even more ideas that I've been tossing around for a while, so I hope to aggregate them into a blog post and eventually add them as work items in CodePlex.  And if you have any ideas for DocProject features please let me know!


Development will target Visual Studio 2008 and the .NET 3.5 Framework, and as I mentioned previously, I'm definitely considering rewriting areas of DocProject as a true VS Package with its own custom editors and project types.  I'm also considering using WPF for the interfaces.  There will be a learning curve but it's one that I'm going to have to accept eventually (and I really do want to learn).


I expect to continue collaborating with community members to find bugs and DocProject's potential for new features.  It seems to me that the experience of DocProject users has been positive, so I'd like to continue working on DocProject in the future in the same way as I've been for the last year.  But if you feel differently please let me know.  Even though it's open source I'd still like to provide an acceptable level of service and support in my free time since the time that I put into helping end-users is also time that I'm putting into DocProject (even if it's just thought), which helps to make a better product even for me to use.


It might also be worth noting that I'm going to maintain the "openness" of DocProject by continuing to introduce new public APIs and areas for extensibility whenever possible.  With the limited feedback that I've received, I'd say that DocProject's high level of extensibility was a success.  A few people have mentioned to me that their businesses have created custom build engine providers [11] and build process components, and I've even used BPCs to help people debug issues in the past.  Actually, my favorite feature of DocProject might actually be the build process component, which, incidentally, doesn't really have anything in particular to do with documentation.


It's hard to predict when the first Production release for DocProject 2008 will be deployed, but if I can use the past year as a metric then I'd say another year from now is certainly reasonable, and possibly even longer than might be required.  To be honest, I think the summer of 2008 is a reasonable goal as long as I keep my eyes on the prize.

Phase 3

At the start of phase 3 I hope to have already achieved my major goals for DocProject, which includes much better integration into Visual Studio and additional features that will make authoring documentation extremely simple and, in many cases, automated.  Thanks to Sandcastle I believe that this goal is attainable.

For the future I think I'm aiming for much better external support so that non-Visual Studio users will be able to benefit from DocProject's features as well.  The team-based features that I mentioned previously might get pushed into this phase, but we'll see how it goes.  And finally, I'd like to hear your ideas for where you'd like to see DocProject go.  After I'm able to meet most of my own goals I'd like to brainstorm with the community to come up with some new and innovative ideas to be a part of DocProject in the future.


[1] Sandcastle on CodePlex,

[2] Microsoft Public License (Ms-PL),

[3] CTP, License and Source Code,

[4] Dave Sexton's Blog: DocProject 1.10.0 RC Preview,

[5] Help authoring tool. (2008, January 9). In Wikipedia, The Free Encyclopedia. Retrieved 11:22, January 17, 2008, from

[6] DocProject Work Items: VS 2008 Shell and Extensibility,

[7] DocProject Components,

[8] DocProject Work Items, Advanced List,

[9] DocProject's Build Process, Build Process Components,

[10] DocProject Sandcastle/Deployment Plug-In,

[11] DocProject tutorial: Creating a Build Engine Provider,

January 15, 2008

DocProject 1.10.0 RC Preview

In this post I'm going to provide details and screen shots of some of the new features in the DocProject 1.10.0 Release Candidate, which includes several bug fixes and new features such as first-class support for conceptual topics (additional content written in MAML markup), some new tool windows for Visual Studio Standard+, and increased performance of the Build Assembler step.

I plan to deploy after the next Sandcastle release, which will give me some more time for additional testing, to ensure compatibility and to finish a few incomplete features.  And BTW, I'm going to try to get back on my monthly deployment schedule again :)

Improved Performance

First, I'd like to start out by saying that performance is something I should have paid closer attention to throughout development, but at some point I just lost focus on it (probably when I started testing exclusively against smaller documentation sets).  So as Sandcastle's performance improved, DocProject's didn't.  I think I may have finally redeemed DocProject in this release though.

A new project option named, Build assembler options allows you to choose from various settings that have a direct affect on the performance of the Build Assembler step:

Build assembler options Description
None The build trace will not contain any output from Build Assembler and it cannot be canceled by a UI command, substantially improving performance.  Choosing this option will disable all other options.
Trace information Informational messages from Build Assembler will be included in the build trace.
Trace warnings Build Assembler warnings will be included in the build trace and the Error List.
Trace errors Build Assembler errors will be included in the build trace and the Error List.
Trace all All messages from Build Assembler will be included in the build trace; warnings and errors will also be appended to the Error List.
Cancelable Build Assembler will be executed asynchronously so that the UI will remain responsive and so that it may be canceled by a UI command, at the cost of performance.

The options that you have chosen will be used whenever Build Assembler is executed, for all types of builds; e.g., reference, conceptual, help 1.x and 2.x.

The default for new projects is Trace errors only, which should provide the same performance as None for a build that does not fail, while providing diagnostic information if it does.

In testing, a substantial speed increase of approximately 8 times is normal when compared to building in Visual Studio and the External UI in the 1.9.0 RC.  The speed is now similar to that of building a DocProject or DocSite on the command-line with MSBuild.  Although, with informational and warning messages disabled there is no log or trace of the tasks that Build Assembler performs and the UI is not responsive while the Build Assembler step is executing.

Enabling Trace all and Cancelable will provide the same behavior as in previous versions of DocProject; i.e., all information and warnings are traced and the build may be canceled at any time.  And although there's an obvious performance penalty with these options enabled, there will also be a noticeable improvement of approximately 5 times compared to 1.9.0 RC.  The speed is now similar to the speed increase garnered by opening a modal dialog during the Build Assembler step in 1.9.0 RC, as per the discovery by Cis in this discussion.  So if you want the Build Assembler step in 1.10.0 to function the same as in 1.9.0, enable these two options and you should still see a speed increase of up to 5 times.

Build assembler options is located under the Build category in the DocProject Properties window.  It's implemented as an enum type with FlagsAttribute, EnumFlagsConverter and related classes (link is to the 1.9.0 RC codebase).

DocProject Topic Explorer New Tool Windows

In preparation for first-class support of conceptual content I had previously written an XmlTreeView control that was included in DocProject 1.9.0 RC.  It extended the FCL TreeView control by adding support for internal and external drag & drop operations, an XML data source and a specialized binding manager.  In 1.10.0 RC it has been refactored and new features have been added so that it's now being used to its full extent in the Topic Management dialog (formerly known as the API Topic Management dialog) and the new Topic Explorer tool window (shown at right).

The new Topic Filters and Topic Editor tool windows were also extracted from the old API Topic Management dialog's Topic Filters and XML Comments tabs, respectively, so that they can be used without having to open a modal dialog (in VS Standard or higher).  Both windows are automatically synchronized to the selected topic in Topic Explorer.  They function as documents although since they're actually tool windows there can only be one instance of them opened at any given time, which means that they can only be used to manage one topic at a time.  Their appearance and functionality hasn't changed since DocProject 1.9.0 RC (preview post) so I'm not going to go into any more detail about them here.

Topic Explorer

The new Topic Explorer tool window is only available in Visual Studio Standard edition or higher.  It can be shown by pressing the Topic Management button on the Sandcastle toolbar and supports docking with other tool windows or floating on its own.  It functions the same as the tree view from the old API Topic Management dialog, with additional features.

Table of Contents

You can drag & drop topics to create the table of contents (TOC) that will be used in compiled help and the DocSite templates.  The TOC will be generated exactly as it appears in Topic Explorer.  Its layout is stored in a file named topics.xml, found in your project's Help\Settings folder.

When you save your changes by clicking Visual Studio's Save All command button or menu item, Topic Explorer will rewrite the topics.xml file based on the current organization of its tree.

Auto-Generated Reference Topics

The Namespaces topic, which is the root API reference topic generated by Sandcastle, starts out as a placeholder topic and loads in the background so that you can manage the TOC without having to wait for Sandcastle.  Once Sandcastle has generated the reflection XML document and the reference TOC, the placeholder is automatically replaced with the Namespaces node (for large documentation sets this may freeze the UI for a few seconds while the tree is being updated).

This node does not appear, however, if your project has no valid project references or external sources.

You can drag & drop the Namespaces topic or its placeholder topic at any time to place it within the TOC; however, drag & drop is not allowed for the individual reference topics.  Neither is dropping a conceptual topic anywhere within the hierarchy of the Namespaces topic.

When saved, the placement of the reference TOC is stored as a single <stoc /> element, which may appear anywhere within the Help\Settings\topics.xml file.

Editing Topics

To open the new Topic Editor window for any particular API reference topic, simply double-click the topic in Topic Explorer.  To edit a conceptual topic simply double-click the topic in Topic Explorer and it will be opened in Visual Studio's XML editor.

I really wanted to provide the same editing support for conceptual topics as is available currently for reference topics, however, I discovered after some experimentation that the MAML schemas are a bit too complex for my simple XmlContentEditor control, and not to mention that HTML is not currently passed through into the final HTML topic as of the Sandcastle Oct. CTP, which would make an HTML-based editor kind of pointless.

In the future I hope to create editors for some of the specific MAML schemas and make them as dynamic as possible.


Topic Explorer's toolbar provides the following functions (from left to right):

Button Description
ToggleExpansion Toggles expansion of all nodes.
Filter2HS Opens or activates the Topic Filters tool window for the selected topic, which provides a document-like UI for the regular expression and categorical filters that are also present in the Topic Management dialog.  Note that you can also filter topics simply by unchecking them in Topic Explorer.
Refresh Synchronizes the tree with the active project.  Topic Explorer is automatically synchronized with the selected DocProject or DocSite in Solution Explorer, although if the topics.xml file is manually updated then the refresh button must be clicked to update the display immediately.  (This should be automatic though in a subsequent release.)
NewFolderHS Creates a new container topic that does not have an associated file, although as of the Sandcastle Oct. 2007 CTP this doesn't appear to be supported so I'll probably just hide the button for now.
NewDocumentHS Creates a new conceptual topic node as a child to the current node and asks the user which conceptual template should be used to create the file on disc.  The file is then opened in Visual Studio's XML editor and the node is placed into edit mode so that the label can be set.  The label is used as the topic's title.
Open Imports existing XML topic files into the project.  Note that existing topics must use MAML to be supported by Sandcastle; however, if a topic does not use MAML then you're free to update it using Visual Studio's XML editor, manually, after it's imported.
Delete Deletes the selected topic after confirmation.  Reference topics cannot be deleted however.  If a container topic (with the folder icon) is currently selected then its entire hierarchy of topics, including itself, will be deleted from the TOC and disc.  If an individual topic is currently selected then only it will be deleted from the TOC and disc, and if it has child topics they will be promoted to children of the deleted topic's parent.

Sandcastle Build Component Editors

I've only actually attempted to create one editor at this time, but expect to see a few more by the time I deploy 1.10.0 RC.  The editor that I've created already is for ResolveReferenceLinksComponent2:


To open this editor simply click the ellipses button (...) of a Reference Link Types component in the DocProject Properties window:

Resolve Reference Links Property

MSDN hyperlink options

These options apply to all hyperlinks that are generated for the MSDN link type.

The Target window option indicates the target for all hyperlinks created by the component for MSDN topics online.  It's implemented as a combo box that accepts the name of a target window (i.e., any string) or one of the values from the drop down list: _blank, _parent, _self or _top.  The default is _blank, which means that clicking the hyperlink to an MSDN topic will open up a new window.

MSDN Locale indicates the default locale to use when generating links to MSDN topics online.  The combo box accepts a custom locale string or you can select one from the drop down list, which is automatically populated with a long list of known locales, none of which are guaranteed to have content on MSDN.  The default value is en-US.

XML reflection file targets

The grid lists each of the individual <targets /> elements of the component, one per row.  You can delete existing rows or add your own.

Base Path is simply concatenated, with respect to file path conventions, to the specified File Pattern.  If a Base Path isn't specified then the current directory is used (most likely being your project's, buildhelp\assembler directory).

File Pattern indicates the XML reflection files from which hyperlinks may be generated.

Recursive indicates whether the Base Path should be searched recursively for files that match the specified File Pattern.

Link Type must be one of the values from the drop down list: None, Local, Index or MSDN.  You can read about the different link types on the Sandcastle blog in this blog post.

Current Tasks

I'm still working on creating some of the Sandcastle Build Component editors and implementing a few work items.

Currently, I've been refactoring the behavior of state persistence for DocProject options.  In previous releases, options are committed immediately when a change is made in the DocProject Properties window and changes are buffered in the Tools Options page.  However, in 1.10.0 RC, options are committed only when the project is saved.  This is done manually by clicking Visual Studio's Save All command button or menu item (and the standard configuration of VS will automatically save the project before each build).  To support this feature, options have been branched into two categories (internally): project and customProject options are those that read and write their state directly using the IAnyProject.Settings property, whereas custom options, for example, might instead persist state to some file.  If you are writing your own DocProjectOptions implementation then you must override the new Save method in order to save changes to custom options.  For your project options (the ones that use IAnyProject.Settings) you shouldn't have to change anything.  The Commit method was used previously for this purpose, but it also was used to commit buffered changes in other situations, without persisting them to disc.  This type of functionality is now only required by the Tools Options page; although, clicking OK on Visual Studio's Options dialog will no longer save the changes to disc - it will only cause Commit to be invoked.  When the project is actually saved, then Save will be called.  In the DocProject Properties window changes are committed immediately, so Commit is never actually called (although that may change - I haven't determined it yet).  To check whether your custom options should be commited immediately have your code read the DocProjectOptions.CommitChangesImmediately property, which is already implemented in 1.9.0 RC.

The purpose of all this is to make sure that the behavior when updating DocProject options is always the same, regardless of whether they are project options or custom options or whether they are being edited in the DocProject Properties window or the Tools Options page.  The difference from previous versions being that changes are committed immediately and only saved to disc when Visual Studio's Save All command is executed.


The next release of DocProject finally provides that long awaited, first-class support for conceptual content.  Now you'll be able to use Visual Studio to easily create, manage and automate the generation of Help 1.x and Help 2.x documentation, optionally in combination with auto-generated API reference documentation.  This feature substantially increases DocProject's potential as a HAT (help authoring tool) and provides a strong foundation for more content-based features in the future.

September 13, 2007

DocSites 1.8.0 Preview

In the upcoming DocProject 1.8.0 release candidate I've made some changes and added several substantial features to the DocSite templates that I'd like to share with you in this blog post. Changes to the DocSite templates include:

DocSite in Solution Explorer
  • ASP.NET Theme presentation:
    • Ships with one default theme named, "BasicBlue", which has the same appearance as the current DocSite templates.
    • Subtle improvements to appearance, mostly for Firefox and Opera.
    • Retained div-only + CSS layout with a sticky footer; i.e., no tables.
    • Includes some useful .SKIN files.
    • Full support for IE6 as well as continued support for IE7, Firefox and Opera.
  • Componentized Master page, with user controls for the header, footer, breadcrumbs, sidebar, TOC and index.
  • ASP.NET Localization with resource-based text in all pages and controls.
  • Customizable and highly extensible full-text search built from the ground up:
    • Designed for general-purpose indexing but customized specifically for indexing HTML help topics.
    • Has a default in-memory search index provider (I'll also build an SQL Server search provider for a subsequent release).
    • Complex query support with operators such as AND, OR, - (not) and grouping with parenthesis.
    • Customizable, factor-based weight and rank calculations.
    • URL query string supports bookmarking searches.
  • Keyword browse page for live browsing of the search index (also supports a URL query string for bookmarking).
  • Administration page for configuring DocSite options, search factors and for viewing simple search statistics.
  • New Project Wizard – Create DocSite Credentials step allows a user to set the administrative DocSite credentials when a DocSite is first created.
  • The DocSite templates reference a new class library that encapsulates common DocSite functions.

Breakdown of Features

The rest of this article will provide more information on some of the features listed above. If you have any questions or comments please let me know!

New Project Wizard – Create DocSite Credentials

The first change that you'll notice to the DocSite templates is a new wizard step:

New Project Wizard - Create DocSite Credentials
Figure 1: New Project Wizard - Create DocSite Credentials

This step allows you to enter an administrative user name and password for accessing the DocSite administration page (more on that later). The credentials are stored in the web.config file in the standard ASP.NET forms authentication section.

For custom DocSite templates authors can easily enable this feature by adding a single user to the authentication section with "$admin$" as the name (the password will be ignored). The mode of encryption that is chosen for the authentication section (e.g., Clear, SHA1, MD5) is reflected in the dialog's help paragraph automatically, and will also be applied to the user's password before it's stored in the web.config file.

Themes and Localization

The DocSite templates now use a default theme named, BasicBlue. Its appearance is almost identical to the appearance of the current DocSite templates, but now it has full support for IE6 as well as a sticky footer for all .aspx pages that do not use an IFRAME to display page content.

Supporting IE6 without a table layout was difficult, but I succeeded with the help of CSS expressions, which are specific to IE (but that means they're supported by IE7 too). The hard part was trying to support IE7's more standardized rendering engine without breaking IE6, and then supporting IE6 without IE7 falling back to things like CSS expressions. But after some flipping out and loss of hair, I finally got it working :)

Customizing the appearance of DocSites should be much easier now that it's fully themed. And with Sandcastle's high level of flexibility, anyone with some previous experience working with XSL and CSS should be able to come up with a custom Sandcastle presentation style and DocSite theme that work together for a completely customized appearance without affecting the DocSite's functionality, or even better, to improve on it. BTW, I'm certainly interested in hearing new ideas for themes if you have any.

Text that appears in all of the DocSite pages and user controls have been extracted into ASP.NET global and local resource files for easy localization.

Indexed Search and Browse

Finding help content in DocSites will be much easier now with the addition of the new search and browse features.

Note: The screenshots depict the Admin link as a different color than other hyperlinks, but that's simply because I clicked it.  What you see is the "followed" hyperlink color.  Before Admin is clicked it's the same color as the other links in the header: blue.

Search Page

DocSite Search Page
Figure 2: DocSite Search Page

The abstract, locale, namespace and library information are all taken from each topic's MSHelp data found in an XML data island generated by Sandcastle for Help 2.x. Although, due to a possible limitation in the next Sandcastle release, I might have to remove this feature temporarily until I can create a custom solution for a subsequent release.

DocSite search supports complex queries with operators that are defined by the search provider itself. By default, your DocSite will support the Boolean AND and OR operators, - (the negation operator) and parenthesized grouping:

DocSite Search Help
Figure 3: DocSite Search Help

The search help page is accessible by simply leaving the search box empty and clicking the search button (the one with the large magnifying glass).

NOTE: In the future I plan on adding an advanced search page that contains HTML topic-specific search functions, such as searching by the culture in which a topic was written, the topic's title, etc.

Browse Index Page

The button with the tiny magnifying glass, next to the search button, is the browse button. Clicking this button will open the browse page using the keywords entered into the search box, although all operators and grouping will be ignored. Clicking the button with an empty search box simply opens the browse page without any selected keywords.

Browse Index Page
Figure 4: Browse Index Page

The browse page allows you to drill down through a query by removing or adding one keyword at a time until you find a result set that contains the topic in which you're interested. The browse page is also useful for administrative purposes as it displays some statistical information about individual keywords as well.

The letter bar at the top of the page provides a list of keywords that start with the selected letter. Clicking a letter will display the keyword list. Then, clicking a keyword will add it to the filter and the new filtered results will be shown. You can continue to browse the index by the first-letter of keywords or view and modify the active filter at any time. The letter bar itself is encapsulated in a user control and is completely customizable using the administration page (discussed later).

Toggle between Search and Browse

The button next to the search query on the search results page and the button next to the keywords on the browse page allow you to easily toggle between these two distinct modes of locating help topics so that you can choose the one that is better suited for your particular query.

The Index

Both the search and browse features work with a full-text index of the HTML help topics generated by Sandcastle. The index is stored in-memory and generated on-the-fly by the website itself, not DocProject, which means that you don't have to rebuild the project to rebuild the index. It also means that you can tweak factors for weight and rank calculations and then rebuild the index on-demand through the web interface, allowing fine-tuning of the search results for common keywords that you might expect your end-users to search against. You can manage the search index and factors through the administration page, which I'll discuss later.

Your DocSite will automatically rebuild the in-memory index after the application has started upon the first request for the search page or a particular keyword on the browse page. In the future I plan on adding an SQL Server search provider that you can use instead of the default in-memory provider so that the index does not have to be rebuilt each time the ASP.NET worker process is recycled or when changes to the application are published that will cause it to restart (like certain modifications to the web.config file).

Site Administration Page

The DocSite administration page provides a set of configurable options with application-scope.

DocSite Administration Page
Figure 5: DocSite Administration Page

To reach this page simply click the Admin link in the top-right corner of your DocSite. If you haven't logged in then you will be brought to the login page first. Enter the credentials that you configured when the project was first created and then click the Login button to continue to the DocSite Administration page.


Settings are stored in the DocSite.config file found at the root of the project. Changes made directly to this file will not take effect until the application is restarted; therefore, I highly recommend using the web interface to configure settings whenever possible so that you do not have to restart the application (and lose the entire in-memory search index).

There are two main categories in the administration page: General and Search. Changes to any options in either category are applied immediately.

The Create Index link allows you to regenerate the index on-demand. This is useful for ensuring that the index is generated immediately after the DocSite has been published and for updating the index after modifying keyword, weight or rank settings.

Client Settings

Letter bar

Configure the characters that will appear in the letter bar at the top of the browse index page. Add characters from your native language or remove existing characters without having to modify any code.

Sidebar size persisted

Controls whether a cookie will be used on the client to remember the last position of the sidebar's handle. This settings is enabled by default.

The Search category has a few subcategories for viewing statistics and managing the DocSite Search and Browse Index pages.

Index Statistics

This category provides read-only information:

Provider name

Name of the current search index provider. DocSiteMemorySearchProvider is the only implementation that will ship in DocProject 1.8.0; however, expect SqlSearchProvider in a subsequent release.

Last creation date

The last date and time that the index was created.

# keywords

The total number of distinct keywords found among all documents that were indexed.

# documents

The total number of HTML help topic files that were indexed.


Provides general index-related settings:

Root search path

Virtual path of the root directory in which the provider will begin the search, recursively. I highly recommend that you do not change this setting.

Public search enabled

Indicates whether unauthenticated users can use the DocSite search feature. Note that if you're logged in after disabling this setting you will still see the search box since it's always available to authenticated users. This setting is enabled by default.

Public browse enabled

Same as the option above but for the DocSite browse index page instead of the search page. This setting is enabled by default.

Keyword Settings

Settings related to indexed keywords and keywords in search queries.

Minimum keyword length

Defines the minimum number of characters that a word must contain in order to be included in the index. This setting is also used to ignore words in queries that have fewer characters than the specified value. The default value is 2.

Excluded keywords

Comma-separated list of keywords that must be excluded from the index and queries. You can add or remove keywords as you see fit.

Hot title keywords

Comma-separated list of keywords that have special semantics in titles of HTML help topics and are used to add additional value to matches in query results through the Title Rank Factors values (below).

You can customize this list if you want to improve search results with queries that contain full or partial matches to these particular words when found in titles.

Weight Factors

Weight factors are integers that affect the weight of indexed keywords. Note that weight is calculated while the index is being created and rank is calculated when a keyword matches a search query. The values in this section do not affect rank directly; however, the weight of a keyword does add additional rank to matches.

Early position keyword

Factor used to calculate the weight of a keyword depending upon its location in the document being indexed. Typically, the earlier the position the higher the weight.

The formula used to calculate weight is:

keyword position / source length * -{value} + {value}

Where {value} is the value of this factor (10 by default).

Title keyword

Factor used to calculate additional weight for keywords found in the titles of indexed documents. The base weight of title keywords is the value of the Early factor (above), but calculated relative to the title and not to the entire document. The value of this factor is then multiplied by the result. The default value is 1.2, which gives 20% more weight to keywords found in titles.

Title Rank Factors

Additional rank values for keyword matches that are found in titles.

Exact title hot keyword match

Additional rank for exact keyword matches found in titles and the Hot title keywords list (above). The default value is 250.

Partial title hot keyword match

Additional rank for partial keyword matches found in titles and exact matches found in the Hot title keywords list (above). The default value is 100.

Exact title keyword match

Additional rank for exact keyword matches found in titles. The default value is 50.

Partial title keyword match

Additional rank for partial keyword matches found in titles. The default value is 20.


In this blog post I described new features to come for the DocSite templates in DocProject 1.8.0 RC. These new features will surely be appreciated by your end-users since they make it much easier than before to locate and browse help topics. As a site administrator you now have a much easier way to configure some of the DocSite features and will have an easier time modifying the appearance and localizing text to meet your particular needs and the needs of your clients.

July 29, 2007

DocProject for Sandcastle 1.7.0 RC Preview

It's about that time again…

Just FYI, DocProject 1.6.2 RC had more downloads in the last month than any other version to date. Thanks to everyone who tried it and provided valuable feedback!

And BTW, I wrote a new article called How to Diagnose and Resolve Issues that provides guidance for gathering diagnostic information if you're having issues with DocProject and would like to try to solve the problem yourself or if you would like to ask for assistance.  You can find other How To... articles here.

In the next version, 1.7.0, there are a number of really cool features that I think people will like, as well as some bug fixes that should solve the problem with Team Build and provide a better experience using the HTML Editor. In this blog post I'll show a preview of some of the new features and describe my plans for them in the future.

Like usual, please let me know what you think so that with your support I can continue to make DocProject a useful community tool.

New Features

  • XML Documentation Editor
  • API Topic (Shared Content) Designer Improvements
  • Missing Dependencies List
  • External UI (DocProject.exe)

I'm still testing and finishing up some other tasks, features and bugs. I'm running a bit late since I was hoping for a mid-July release, but a few of the features that I will describe below somehow snuck into this release (that seems to happen a lot with me ;). I'm also quite busy with work but I think I might be able to manage a deployment next week, without any showstoppers popping up. So far, things are looking good though.

XML Documentation Editor

The API Topic Management Dialog now supports authoring XML documentation (summary, remarks and example) for all API members, not just the project and namespace summaries. See Figure 1 below.

I've created a new control named, ContentEditor and another control named, ContentListEditor, which is used for the new and improved content dialogs: API Topic Management (Figure 1) and the API Topic Designer (Figure 4). As you can see in both figures, there are now two tabs at the bottom for switching between design-mode and source-mode and a list of items that can be edited. Only one item can be edited at a time by selecting it in the list. After editing an item its name becomes bolded in the list until you save your changes.

Note: The content editor control actually provides another tab named, Preview, which raises an event that controls can handle to provide read-only HTML based on the changes made in the editor. Because this feature has not been implemented yet the Preview tab is currently hidden at runtime.

Figure 1: API Topic Management – Xml Documentation Editor

Xml Documentation

Remember that this is an xml documentation editor, which means that tags such as see, c and code may be used in Source mode even though they won't be formatted in Design mode. Sandcastle uses these tags when it builds your documentation to apply special formatting or to link to other topics.

One feature that I plan on adding in the future is the ability to drag nodes from the tree onto the designer and have it serialize <see cref="{id}">name</see> automatically. I'd also like to show see links as hyperlinks in the designer, but maybe as green or using double-underline to distinguish them from normal hyperlinks. Another possibility is to use the stylesheets from your DocProject's or DocSite's selected presentation style and then format all of the xml documentation tags in the designer as they will appear in the compiled documentation.

Another feature that I plan on adding is API type-specific sections in the item list. In other words, if you select a method node to edit then the editor should automatically list each of the method's parameters next to summary, remarks and example. Tags such as permissions and seealso should be listed as well, although I'd like to open a custom editor interface for these tags.

Currently, you can add custom tags to the list using DocProject's configuration file (DaveSexton.DocProject.dll.config, normally found in C:\Program Files\Dave Sexton\DocProject\bin), but they'll apply to every API element. I'd like to implement a feature that allows you to specify which sections apply to which API elements though (probably using DocProject's configuration file, partially shown in Figure 2 below).

Note: Do not confuse the DaveSexton.DocProject.dll.config file with the DocProject.exe.config file (I'll explain more on that below) located in the same directory.

Figure 2: DaveSexton.DocProject.dll.config xmlDocumentationTags attribute

HTML to XML Conversion

I've made a few improvements to my HTML Editor control and the way HTML is converted to XML (a few bug fixes).

The HTML Editor control that you see in Figure 1, which you may already be familiar with if you've used DocProject 1.6.0, is based on the WebBrowser control. The WebBrowser control is basically a managed wrapper around Internet Explorer. For the HTML Editor it's a wrapper around IE's design mode, which only produces HTML markup (in some cases, very poor HTML markup.) Sandcastle requires valid XML, so DocProject converts your HTML to XML automatically. The results of the conversion can be viewed in Source mode. The markup that you enter in Source mode is also converted automatically, so don't be surprised if when you forget to add a closing p tag, DocProject adds it for you when switching views or saving your changes :)

The HTML Editor is a work-in-progress, so I expect issues with HTML to XML conversions to spring up every now and then. Please let me know if you experience an error. If you can provide me with the exact steps to reproduce the problem and the markup that you used, I'll do my best to fix parser bugs and improve the editor's usefulness.


Your comments are saved in individual xml files in your DocProject's or DocSite's Comments folder, at the root of the project. An {assembly name}.xml file is created for each assembly and one project.xml file is created to contain the project and namespace summaries. If you prefer you can edit these files using Visual Studio's XML editor. If you haven't edited any API elements for a particular assembly then its XML file will not be present in the Comments folder, but you can create it yourself. The name of an assembly's xml documentation file must be the display name of the assembly with .xml appended to the end or else DocProject will not be able to merge your documentation with imported documentation.


XML documentation that appears in your code is not shown in this dialog. By default, comments created in the dialog overwrite code comments, on a section by section basis; e.g., summary, remarks or example. But you can change this setting to give code comments precedence instead of being overwritten by selecting KeepSource for the Merge xml documentation setting found in Tools > Options > DocProject > Active Projects > Content.

Figure 3: Merge xml documentation options for documentation written in the API Topic Management dialog

As you can see in the figure above, the API Topic Management dialog can be accessed from the option immediately below the Merge xml documentation option.

Xml Documentation Clean-up

If you create documentation for a type that is later removed from your project then the documentation will still remain in the XML file for the assembly in which the API element is defined, however it will no longer be displayed in the API Topic Management dialog so you must remove it from the file manually. In the future I may add a feature that will allow you to clean up your xml documentation files at the click of a button.

API Topic (Shared Content) Designer Improvements

The API Topic Designer uses the new content list editor control and provides a list of content items that you can edit, such as the header, footer and various titles.   The items are loaded from the Presentation\Style\Content\shared_content.xml file in your DocProject or DocSite.  Changes to the items using the dialog are written directly to this file as well when they are saved.  Deleting an item in the file will remove it from the list and adding an item to the file will add it to the list the next time the dialog is opened.

Figure 4: API Topic Designer in 1.7.0

Just like in 1.6.0, the API Topic Designer appears as a step in the New Project Wizard with all of the new features.  The header section is the default item selected.

As of the June 2007 CTP release of Sandcastle, presentations have a hard-coded header and footer that will probably be inappropriate for your projects.  I've decided not to handle this in DocProject so you must delete the header and footer manually if you do not want them to appear in your documentation.  Although the New Project Wizard is a good place to do that, you can still update the header and footer at a later time using the API Topic Designer.

FYI, I've already requested in the forums that the Sandcastle team set these values to empty in the default presentations to save effort on behalf of end-users.

Text-only Content Items

Not all of the items are XML-editable using the API Topic Designer. Most are text-only since there will probably not be a need to use HTML formatting for them. Text-only items only show the Source tab and will escape any XML markup that you enter. To configure which items use the HTML editor on a per-presentation basis you must edit DocProject's configuration file (DaveSexton.DocProject.dll.config, normally found in C:\Program Files\Dave Sexton\DocProject\bin):

Figure 5: DaveSexton.DocProject.dll.config sharedContentXmlItems attribute

Missing Dependencies List

A while back, around version 1.3.0, I attempted to build documentation for DocProject using DocProject itself but I quickly found that a bug in Sandcastle's MRefBuilder program (actually, CCI) relating to binding redirection prevented me from doing so. In the last version, 1.6.2, I decided to try again but this time I found that DocProject's ReferenceResolver class wasn't able to resolve the Interop.MSHelpCompiler.dll reference (provides the Help 2.x compiler services) for the Sandcastle project (DaveSexton.DocProject.Sandcastle.dll). The problem is that DocProject's Sandcastle assembly is being resolved in the GAC, but the MSHelpCompiler interoperability assembly is not installed in the GAC, so it cannot be found. I do plan to fix this bug in a future release, but since I've expierenced this issue myself I assume that there may be other scenarios that cannot be handled automatically by the reference resolver.  This features was added so that users can manually provide the path to dependencies that cannot be resolved automatically.

FYI, nobody has actually mentioned any problems with DocProject's automatic discovery of source dependencies so I assume that this feature will be used quite rarely, if at all. But then again, it must be used by DocProject itself just to build its own documentation ;)

I suggest that you do not use this feature unless you get an error when building. The error will be produced by Sandcastle's MRefBuilder utility and will state something about one or more unresolved dependencies, mentioning the full assembly name as well. From the information in the build output window you should be able to locate and add the missing dependency yourself using the new dialog:

Figure 6: Missing Dependencies List

This dialog is similar to the External Sources dialog that was added to DocProject 1.6.2 RC. You can find both dialogs in Tools > Options > DocProject > Active Projects > Build.

To add an assembly (.dll or .exe that cannot be resolved automatically by DocProject) to the list you must enter the full path and name into the text box in the new row (the row with the *) or click the button with the ellipses on the right side to select a file. You can also edit existing rows or delete rows by clicking the row header and pressing the Delete key.

The button on the left side of each row will map an absolute path to a path that is relative from the project's root directory, like the example path in Figure 6. This is useful for team and build-server scenarios.

External UI

DocProject 1.6.0 provided preliminary support for Visual C# Express and Visual Basic Express editions of Visual Studio. Unfortunately, because add-ins are only supported by Visual Studio Standard and higher, Express users had to manually edit the project files of DocProjects and DocSites to configure them after using the New Project Wizard since all of DocProject's options and dialogs are hosted by the add-in.

DocProject 1.7.0 RC has an external UI that uses a property grid, just like DocProject's Active Projects tools options page, so Express users can configure their DocProjects and DocSites using the same tools as Visual Studio Standard+ users: 

Figure 7: DocProject.exe

For Standard+ users, though this feature may be handy at times, I still recommend using Visual Studio in most situations to configure your DocProjects (via the tools options pages) and to build them in Visual Studio since it will automatically build dependency projects for you. Also, the Include Project Output Dialog does not work in the external UI and if you add an image to the XML documentation editor or the API Topic Designer while using the external UI, the image will not be included as a project item in Visual Studio (although it will still be imported into the Art folder - you'll have to Show All Files and include it manually).

Automatically Open the Active DocProject

You can add a link to the program in Visual Studio for quick access by going to Tools > External Tools... and clicking Add (this can be done in Visual Studio Standard and higher as well if desired).

By specifying the arguments in Figure 8 below, when you run the External UI from Visual Studio's Tools menu the program will automatically open the active DocProject or DocSite in Solution Explorer (that is, the project that contains the current file that is opened or the current file/folder that is selected in Solution Explorer).

The DocProjectBuildPath environment variable used in Figure 8 is registered on your system when you install DocProject.  It points to DocProject's bin directory, commonly found at C:\Program Files\Dave Sexton\DocProject\bin.

Figure 8: DocProject.exe - Visual Studio Tools Registration

Building DocProjects and DocSites

While developing this program I realized that it would be quite easy to build a DocProject from this interface using DocProject's BuildController class, so I gave it a shot. It actually worked so well that I now build my test DocProjects and DocSites using the GUI for debugging purposes. Breakpoints in code being hosted by Visual Studio's process tend to time-out after a few seconds of inactivity, due to COM issues, but since DocProject.exe is fully-managed it makes it much easier to attach, debug and continue, without having to restart Visual Studio and load up an entire solution.

Figure 9: DocProject.exe build trace

DocProject.exe will not only build your DocProject's or DocSite's help, but will also build the project's assembly output using MSBuild first (remember, DocProjects and DocSites are MSBuild projects). During a build you'll see descriptive status information describing the current step and the progress bar, just like you see in Visual Studio. You can even cancel builds at any time.

The program will also remember some settings for when you restart, such as the last position, size and window state, with multi-monitor support, the position of the toolbars and the height of the build trace window (Figure 9).

Currently, this program does not support DocProjects and DocSites that have managed C++ projects as sources since they can only be built using a solution file, but I plan to look into implementing that feature in a future version of DocProject.

DocProject.exe Extensibility

The code that is used to configure DocProjects and DocSites in Visual Studio Standard+ is the same code that is executed by the external UI. This means that if you have created a custom build engine provider for your organization it will automatically work with the external UI. Not only does this include the options in your DocProjectOptions implementation, which will appear as new properties in the grid, but also any Visual Studio toolbars that are created by your provider will appear as well. For example, in Figure 7 above you can see the Sandcastle toolbar that appears in Visual Studio Standard and higher in the DocProject UI (the right-most toolbar).

Sandcastle and Sandcastle/Deployment are examples of build engine providers that are registered in DocProject's configuration file (DaveSexton.DocProject.dll.config, commonly found in C:\Program Files\Dave Sexton\DocProject\bin).  Several of the options that appear in the figures above, including the API Topic Designer and Management Dialogs are provided by the Sandcastle build engine provider plug-in.

The next major How To... article on my to-do list is guidance for creating custom providers that can be used across projects in an organization, but if you feel like testing the waters yourself check out the DaveSexton.DocProject.Sandcastle and DaveSexton.DocProject.DeploymentSandcastle projects in the source code and try creating your own plug-in.


With the 1.7.0 RC, Visual Studio Express users will be able to do much more with DocProject than they could before with the new VS-like external UI. As a documentation author, you'll be able to write long examples and remarks sections using an HTML Editor and store all of the comments in your DocProject's Comments folder, which is merged with your xml code comments automatically before each build. You'll also be able to use the HTML editor to design topics' shared content, such as the header and footer – like before – but with the addition of every other item that appears in Sandcastle's shared_content.xml file as well. And now you can configure your DocProjects and DocSites to reference dependencies that could not be resolved automatically, however rare that might be.

I hope you like the new features and I look forward to receiving your feedback.

June 26, 2007

DocProject for Sandcastle 1.6.2 Release Candidate

DocProject 1.6.2 was released and is now available for download on CodePlex.

I want to thank all of DocProject's users that took the time to report bugs and provide diagnostic information to me. You've been helpful.

Recently, Anand blogged about DocProject and some of the other community projects that can automate Sandcastle to generate help for managed APIs. After his post, DocProject's rate of download increased by three times and then kept increasing. And since then I've certainly received more feedback than usual. Thanks Anand!


The latest release addresses some issues that users were reporting relating to the refresh version of the June 2007 CTP of Sandcastle, which was released a few days after its original release. I would have updated DocProject sooner if I knew :)

There is also support now for adding external sources (assemblies and corresponding xml documentation). This new feature also provides support for Web Site Projects since you must use a Web Deployment Project to generate a managed assembly, which can be added as an external source for your DocProject or DocSite.

In Progress

Currently, I'm looking at providing the ability to create and manage custom topics. I noticed that in Sandcastle's June 2007 CTP refresh there are some transformations and files related to conceptual topics. That sounds interesting to me and may be the feature that people have been asking me to add. I'll definitely research this more.

June 15, 2007

From Setup and Deployment to Self-Extracting Installer

In this blog post I'm going to describe how you can use a Setup and Deployment project in Visual Studio 2005, along with a few other tools, to create a single, self-extracting executable to install your managed software and prerequisites. I'm also going to provide a solution to one of the problems that I encountered when I recently attempted to create a self-extracting installer for one of my open source projects.


Using a Setup and Deployment Project in Visual Studio, you can easily build a single Windows Installer file (.msi) that allows you to redistribute your custom software to your end-users, providing an automated and familiar setup experience. If your software depends on other software such as the Microsoft .NET Framework 2.0, as it probably will, then you can install them as prerequisites by having your Setup and Deployment project create a Generic Bootstrapper executable - Setup.exe. End-users should execute the bootstrapper instead of the .msi so that it will discover which dependencies are missing on the target machine, download and install them. The bootstrapper will then automatically run the .msi to install your software as long as the prerequisite installations were successful.

You can also develop custom Generic Bootstrapper packages and have them show up in Visual Studio's Prerequisites dialog, along with predefined packages such as the Microsoft .NET Framework 2.0 and Windows Installer 3.1. Custom packages can be configured to download the prerequisites from a website or they can be deployed along with the bootstrapper executable and your project's .msi file in their own sub-directories, which is extremely useful if the prerequisites are not available for download from some third-party website and if you don't have the means or desire to host them on your own web server.

User Experience

Having a bootstrapper to automatically install your software's dependencies is obviously useful, but your end-users will probably expect a single file to install your software and might be surprised to discover that they must download a Setup.exe file and an .msi file. You may also be tempted to deploy a Readme.txt file along with the installers to instruct users to run the Setup.exe program instead of the .msi. If you have added custom prerequisites to your bootstrapper then you may have to deploy them along with the installers as well if they aren't available for download from a web server. But since your end-users aren't going to be happy having to download several different files and then manually create the appropriate folder structure expected by Setup.exe, you're forced to zip all of the files and sub-directories together. An end-user must unzip the files, browse to the target directory in Windows Explorer and then double-click the Setup.exe file to start the installation.

All-In-One Deployment

So how about deploying a single, self-extracting executable that can dump all of the files into a temporary directory and then run the Setup.exe program automatically? There are several commercial products that can produce self-extracting zip files, but if you're like me you'd prefer a no-cost solution for something as simple, practical, and as seemingly common as having a single executable to install custom software.

Enter IExpress. Pre-installed on Windows systems, this program can create a self-extracting installer by compressing the files of your choice and may be configured to execute your Setup.exe bootstrapper upon extraction. The result can be distributed as a single, stand-alone file that contains the bootstrapper executable, any prerequisites that must be deployed along with your installer, and the .msi installer itself. That's right, pre-installed on Windows!

Start > Run > iexpress

The Directory Structure Problem

However, this amazing tool doesn't come without some pain. IExpress 2.0, the current version that ships with Windows Vista, doesn't preserve the folder structure of the files that it compresses. But the Setup.exe bootstrapper program is automatically built to look for each prerequisite that is not already being downloaded from a web server, in a local folder of the same name as the prerequisite itself. This obviously presents a problem when using IExpress since it will extract each prerequisite installer into the same temporary directory as the Setup.exe bootstrapper. Running a simple test reveals that the Setup.exe bootstrapper complains that it cannot locate one or more of the prerequisite installers.

But have no fear, there is a way. In order to better explain the process of using IExpress to extract and run the Setup.exe bootstrapper program with local file dependencies I'm going to use an example.


DocProject is software that I've written to integrate Microsoft's managed API documenter, Sandcastle, into Visual Studio 2005. Up until the 1.6.0 Release Candidate of DocProject its installer shipped as a stand-alone Windows Installer file (.msi). But as of 1.6.0, a few of Microsoft's Primary Interop Assemblies for Visual Studio have become a prerequisite (namely, Microsoft.mshtml and stdole), which means that vs_piaredist.exe must be deployed along with the .msi. In order to ensure that end-users have Microsoft's redistributable assemblies installed on their systems before the DocProject installer is executed, I've create a Generic Bootstrapper package for vs_piaredist.exe that is required by DocProject's Setup and Deployment project.

As described in the introduction, DocProject's Setup and Deployment project builds a Setup.exe bootstrapper that checks for the prerequisites on the target machine and then, if the prerequisites aren't found, executes the vs_piaredist.exe file to install them. After the prerequisites are installed or skipped, the Setup.exe program then runs the .msi to install DocProject on the user's system.

When researching DocProject's prerequisites I discovered that Microsoft does not provide vs_piaredist.exe over the web, which means that I could have either zipped it with DocProject's installer, hosted it on my own web server, or figured out a way to include it into IExpress. I chose the latter since it requires the least amount of effort on mine and the user's part, but wasn't sure how it could work or if it was even possible at all.

Solution to the Directory Structure Problem

The Setup.exe bootstrapper is actually a generic executable that has a few null resources. When you build a Setup and Deployment project that has prerequisites, the MSBuild GenericBootstrapper Task is used to make a copy of the generic Setup.exe program. The copy is then loaded with a resource file that tells the bootstrapper how to install your program's prerequisites. Unfortunately, the MSBuild task doesn't provide the option to have the configuration resource use prerequisite installers found in the target directory, so you must manually update the appropriate resource file to remove the hard-coded path that looks for prerequisites in a sub-directory of the same name.

Sounds scary, but it's actually quite easy to do. Here are the instructions to create DocProject's installer:

  1. Build the Setup and Deployment project.
  2. Open the Setup.exe program in Visual Studio's resource editor:
    1. File > Open > File (or Ctrl+O)
    2. Browse to the bin directory of the Setup and Deployment project and you'll find the Setup.exe file in the folder for the current configuration (e.g., Debug or Release), along with the other installer output.
  3. Double-click the resource named, SETUPCFG in the 41 folder
  4. Search for vs_piaredist\, exactly like that - with the trailing slash. Two (2) occurrences should be found. For each, make sure the entire vs_piaredist\ string is highlighted and press the Delete key to remove it from the resource.
  5. Save the resource file and the Setup.exe executable will be updated automatically.
  6. Start > Run > iexpress
  7. Create a new package by following the IExpress wizard's steps and make sure to include the following files:
    1. The Windows Installer file (.msi).
    2. The Setup.exe bootstrapper file.
    3. The vs_piaredist.exe file.
  8. Note: You should select the Store files using Long File Name inside Package option in one of the last wizard steps.

Step #4 is how to reconfigure the Setup.exe bootstrapper to look in the current directory for vs_piaredist.exe instead of in a subdirectory of the same name. We do this by simply removing the folder from the path in two different locations within the same resource file.

You should repeat step #4 for each of the local prerequisites that your Setup.exe bootstrapper will install, but instead of vs_piaredist\ use the name of the folder as it appears in your Setup and Deployment project's bin directory.


Visual Studio's Setup and Deployment project, the Generic Bootstrapper and IExpress are powerful tools that you can use to create installers for your custom software.  Using IExpress to build a self-extracting installer that automatically runs your software's Setup.exe bootstrapper requires additional steps if the bootstrapper depends on prerequisite installers that are deployed with your software. By using Visual Studio's resource editor you can modify the Setup.exe file to look for prerequisites in the current directory.  This allows you to build a self-extracting installer that contains all of your software's depencencies, providing a nice installation experience for your end-users.