How-To Add Custom Help Functionality

 

Updated: June 7, 2016

Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista

This sample shows you how to create a snap-in that defines its own custom functionality to display snap-in context Help. When the snap-in provides its own custom Help solution, the MMC standard Help Topics window continues to be displayed only in response to clicking the Help Topics on the Help menu on the MMC console. In its place, when an item has been selected, the custom snap-in Help mechanism is invoked in response to these user actions:

  • User clicks the Action menu on the MMC console, and selects the Help menu item.

  • The user clicks the Help action in the actions pane.

  • The user right-clicks a node and selects Help.

  • The user presses the F1 key.

System_CAPS_noteNote

This new feature is available only for managed snap-ins.

For the custom help feature to work, a hotfix needs to be installed. Download information on the hotfix is available here.

This procedure will guide you, step-by-step, in using the custom Help features of your managed snap-in. If you choose C#, you can start by creating a file called CustomHelpSnapIn.cs.

How to create a snap-in that provides custom Help

  1. Add the using directives that reference the assemblies that are required for this sample. The first directive is a reference to Microsoft.ManagementConsole which is the MMC 3.0 assembly; the second directive is a reference to the System.ComponentModel assembly that is the source of the RunInstaller attribute. The last assembly allows us the use of a message box to illustrate the custom Help capability. Add the PermissionSetAttribute attribute to allow security actions for a permission set to be applied to code using declarative security.

    using Microsoft.ManagementConsole;
    using System.ComponentModel;
    using System;
    using System.Security.Permissions;
    using System.Windows.Forms;
    [assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Unrestricted = true)]
    
  2. Define a namespace for the sample.

    namespace Microsoft.ManagementConsole.Samples
    
  3. Installutil.exe is a command-line utility that ships with .NET. It requires an Installer-derived class to be declared within the target assembly and further requires that the RunInstaller attribute be defined. To derive a class, use SnapInInstaller. It automatically discovers registration information in the assembly and registers the discovered snap-ins. Set the RunInstaller attribute to True. This provides an entry point for tools such as Installutil.exe to execute the framework installer code.

    /// <summary>
    /// RunInstaller attribute - Allows the .NET Framework Installutil.exe to install the assembly.
    /// SnapInInstaller class - Installs the snap-in for MMC.
    /// </summary>
    [RunInstaller(true)]
    public class InstallUtilSupport : SnapInInstaller
    {
    }
    /// <summary>
    
  4. Add the attribute SnapInSettingsAttribute. This attribute must be defined for any snap-in that must be featured on the Add/Remove dialog box in the MMC. This attribute defines the GUID for the snap-in, a display name for the snap-in, and a short description of the snap-in. Remember to add the UseCustomHelp property.

    /// <summary>
    /// SnapInSettings attribute - Used to set the registration information for the snap-in.
    /// SnapIn class - Provides the main entry point for the creation of a snap-in. 
    /// CustomHelpSnapIn - Provides a specific Help topic for its rootnode.
    /// UseCustomHelp setting attribute informs MMC that this snap-in will provide its own custom help implementation.    
    /// </summary>
    
    [SnapInSettings("{6732A1ED-C9BF-4c01-A5E5-9C779D1A73C8}",
         DisplayName = "Custom Help Implementation Sample",
         Description = "Show callback functionality",
         UseCustomHelp = true)
    ]
    
  5. Define a new class CustomHelpSnapIn that is derived from the SnapIn class. Create a new scope node and assign it to be the root node for the snap-in. Give the root node a display name. Create two child nodes, assign a display name to each, and add them as children to the root node.

    public class CustomHelpSnapIn : SnapIn
        {
            /// <summary>
            /// Snap-in Constructor
            /// </summary>
            public CustomHelpSnapIn()
            {
                this.RootNode = new ScopeNode();
                this.RootNode.DisplayName = "Root Node (Custom Help Sample)";
                ScopeNode child1 = new ScopeNode();
                child1.DisplayName = "First Child Node (Custom Help Sample)";
                ScopeNode child2 = new ScopeNode();
                child2.DisplayName = "Second Child Node (Custom Help Sample)";
                //Relate the child nodes to the root node
                this.RootNode.Children.Add(child1);
                this.RootNode.Children.Add(child2);
            }
        } // class
    
  6. Define a custom DisplayHelp function.

    // Define a cutom Help implementation.
    private void DisplayHelp(object obj)
    {
        // The custom message that is shown illustrates 
        // that you can use the object to get the context and customize the Help accordingly.
        MessageBox.Show("This message illustrates that it is a Help implementation for : " + ((ScopeNode)obj).DisplayName, "Custom Help provided by snap-in");
    }
    
  7. Register the DisplayHelp function as a callback by adding this line of code to the snap-in class definition.

    // Register the DisplayHelp method as the custom Help callback.
    SnapInCallbackService.RegisterSnapInHelpTopicCallback(this, DisplayHelp);
    
  8. When you run the sample code, a different customized message box will appear, depending on the context in which the Help is requested. This illustrates how the callback method can be custom coded to render specific Help based on the requirements of the snap-in. The complete sample code for CustomHelpSnapIn.cs is given in the following example section. Compile the code to create the CustomHelpSnapInSample dll. The code for this sample is available in the <MMC 3.0 Samples>\CusomHelpSnapInSample directory.

System_CAPS_noteNote

The UseCustomHelp setting attribute is used to register a snap-in level callback function which is subsequently invoked by MMC when help is requested. Setting the UseCustomHelp attribute causes any other help mechanism defined using the HelpTopic property to be ignored, unless the registered callback function is explicitly coded to make use of the HelpTopic property in the scopenode, property page, or selection data context.

Steps to create, install, and run the snap-in

  1. To install this snap-in, run the .NET Framework InstallUtil.exe program using the following command-line command: InstallUtil.exe SimpleSnapInSample.dll. Be aware that if the Microsoft.ManagementConsole dll is not in the GAC, both the Microsoft.ManagementConsole.dll and the CustomHelpSnapInSample.dll must be in the same directory. To uninstall the snap-in later, run the previous InstallUtil.exe command with the /uninstall switch.

  2. The InstallUtil.exe command installs your snap-in using the SnapInSettingsAttribute. The utility creates an InstallUtil.InstallLog file to show the success or failure of the install and the actions that were taken.

  3. InstallUtil.exe populates the registry entries for the given snap-in under the HKLM/Software/Microsoft/MMC/SnapIns key.

  4. After the snap-in is installed, the Snap-in is visible to MMC and can be added to the MMC Console using the Add/Remove dialog. To test this snap-in, run MMC 3.0 (mmc.exe) and use the Add/Remove Snap-in menu. The SimpleSnapIn appears in the Add dialog and can be loaded in the MMC console.

The following is a complete code example for CustomHelpSnapIn.cs.

//=======================================================================================;
//
//  This source code is only intended as a supplement to existing Microsoft documentation. 
//
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE.
//
//  Copyright (C) Microsoft Corporation.  All Rights Reserved.
//
//  Description:
//  Uses the UseCustomHelp attribute to indicate that the snap-in provides its own help functionality. 
//  Uses the DisplayHelp method to show customized help for each node in the snap-in.
//
//=======================================================================================;

using Microsoft.ManagementConsole;
using System.ComponentModel;
using System;
using System.Security.Permissions;
using System.Windows.Forms;


[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Unrestricted = true)]

namespace Microsoft.ManagementConsole.Samples
{
    /// <summary>
    /// RunInstaller attribute - Allows the .NET Framework Installutil.exe to install the assembly.
    /// SnapInInstaller class - Installs the snap-in for MMC.
    /// </summary>

    [RunInstaller(true)]
    public class InstallUtilSupport : SnapInInstaller
    {
    }
    /// <summary>
    /// SnapInSettings attribute - Used to set the registration information for the snap-in.
    /// SnapIn class - Provides the main entry point for the creation of a snap-in. 
    /// CustomHelpSnapIn - Provides a specific Help topic for its rootnode.
    /// UseCustomHelp setting attribute informs MMC that this snap-in will provide its own custom help implementation.    
    /// </summary>

    [SnapInSettings("{6732A1ED-C9BF-4c01-A5E5-9C779D1A73C8}",
         DisplayName = "Custom Help Implementation Sample",
         Description = "Show callback functionality",
         UseCustomHelp = true)]
    public class CustomHelpSnapIn : SnapIn
    {
        /// <summary>
        /// Snap-in Constructor
        /// </summary>
        public CustomHelpSnapIn()
        {
            this.RootNode = new ScopeNode();
            this.RootNode.DisplayName = "Root Node (Custom Help Sample)";
            // Register the DisplayHelp method as the custom Help callback.
            SnapInCallbackService.RegisterSnapInHelpTopicCallback(this, DisplayHelp);
            ScopeNode child1 = new ScopeNode();
            child1.DisplayName = "First Child Node (Custom Help Sample)";
            ScopeNode child2 = new ScopeNode();
            child2.DisplayName = "Second Child Node (Custom Help Sample)";
            //Relate the child nodes to the root node
            this.RootNode.Children.Add(child1);
            this.RootNode.Children.Add(child2);
        }
        // Define a cutom Help implementation.
        private void DisplayHelp(object obj)
        {
            // The custom message that is shown illustrates 
            // that you can use the object to get the context and customize the Help accordingly.
            MessageBox.Show("This message illustrates that it is a Help implementation for : " + ((ScopeNode)obj).DisplayName, "Custom Help provided by snap-in");
        }

    } // class
} // namespace
Show: