MMC Programming Elements
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
It is useful to be familiar with the programming elements offered by MMC before you undertake the task of designing a snap-in. The purpose of the MMC 3.0 SDK is to design snap-ins. The snap-in contains the actual workings of a management task. It is designed to run within the context of the MMC. The MMC 3.0 SDK facilitates the design of a snap-in to encapsulate either a specific management task or a set of operations. It allows the snap-in development to focus on the objects to be managed and the methods used to manage the objects. A snap-in can either be a stand-alone snap-in, thereby providing independent programmatic functionality, or it can be an extension snap-in that extends the operations of a specific snap-in, and is dependent on the parent snap-in to operate. For example, a simple mail transfer protocol (SMTP) snap-in may be an extension snap-in that relies on the IIS snap-in.
The following are useful decision steps to consider before starting:
Identify the management space and determine what type of snap-in best suits your needs. Decide whether your management tasks should exist as part of a stand-alone snap-in, be put into an extension snap-in, or reflect a combination of both. A stand-alone snap-in is capable of performing its designated management task as the only snap-in loaded in the snap-in console. When loaded in a snap-in console that contains multiple snap-ins, a stand-alone snap-in appears as a child of the MMC root node and operates independently from any of the other stand-alone snap-ins in the snap-in console.
In contrast, an extension snap-in adds functionality to a stand-alone snap-in. The additional functionality can be represented using additional child nodes under an existing stand-alone snap-in node in the tree.Layout the namespace, and decide what objects or containers belong in it. The organization of the scope tree is critical to the success and usability of your snap-in. While mapping the management space to the scope tree, it is important to understand the node types, understand how to organize the tree based on user tasks and roles, and know how to summarize data and user inheritance models.
Design the UI to present information about the managed objects.
Define the management tasks for each object in the namespace.
Start writing the snap-in code using the MMC 3.0 Managed Code Framework.
As a snap-in designer, it is useful to separate the core management functionality from the presentation. It is useful to think of the programming elements that are offered by MMC and associate management tasks with their functionality. After this is done, it is easier to map the desired UI to the UI that MMC offers in association with each of these elements. For example, the UI for the tree pane is relatively static (a tree) while the UI for the results pane is more flexible. Accordingly, it is useful to identify the static nodes in the management space and map them to scope nodes. It is possible to choose any of the supported view types in MMC for each scope node. A good snap-in design should be able to provide the management logic and data and rely on MMC to provide the infrastructure to design the UI to offer the related views.
The MMC namespace represents the hierarchy of objects and containers that are displayed in the console window.
In this Topic
Snap-in
Use of Attributes Programming Model
Scope Node
Result Node
Actions
Standard Verbs
Views and View Descriptions
Using Selection Data
Utility Programs
Property Sheets and Pages
Wizards
Dialogs
Localization
Threading
Checklist for Snap-in Design and Development
Snap-in
The SnapIn class provides the abstraction for the core binding of a snap-in dynamic-link library (DLL) and provides the initial instantiation point of the snap-in code. To show the snap-in in the tree pane, the RootNode property of the snap-in must be set to a scope node. A snap-in can be either a stand-alone snap-in or an extension snap-in.
Use of Attributes Programming Model
MMC uses attributes to store essential metadata. Attributes accept two types of parameters: positional parameters and named parameters. Positional parameters are like constructor arguments and their signature matches one of the constructors of the corresponding attribute class. Named parameters are defined as non-static properties in the attribute class declaration. They are optional and, when used, their names should exactly match the name of the property that is defined in the attribute class declaration.
MMC uses both positional parameters and named parameters. For example, the SnapInSettingsAttribute is used to provide a GUID, a display name, and a description for the snap-in. For MMC to recognize that a snap-in is available on the system, that snap-in must be registered. Snap-in registration data consists of a set of registry keys and values that describe how and when to load the snap-in.
Attributes allow a snap-in to be registered with minimal additional code requirements on the part of the snap-in developer. It uses reflection to examine the snap-ins and extract metadata. For more information about the use of attribute programming, see Providing Metadata Descriptions About Your Component. The following attributes are available:
ExtendsNodeTypeAttribute
This is an optional attribute for a snap-in that specifies which node types it can extend. Multiple instances of this attribute may be applied to a single SnapIn class.
NodeTypeAttribute
This is an optional attribute that is used to define the registration information for a node. If a node does not have this attribute, it will not be registered as an extensible node. This attribute is applicable to a scope node. The value of this attribute contains the node type GUID of the scope node.
PublishesNodeTypeAttribute
This is an optional attribute that is used to define the registration information for a node. If a node does not have this attribute, it will not be registered as an extensible node. This is an attribute applicable to a snap-in and its value contains the node type GUID for a scope node or selected items in a view that can be extended. More than one PublishesNodeTypeAttribute are applicable to a snap-in.
SnapInSettingsAttribute
This attribute is used to define the registration information for a snap-in. A single instance may be applied to a class that is derived from a snap-in. Both primary and extension snap-ins have the following registry keys and values associated with them. Some entries are optional and may or may not exist for a given snap-in. InstallUtil.exe will populate the registry entries for a given snap-in under HKLM/Software/Microsoft/MMC/SnapIns, as listed in the following table.
Path |
Description |
FX:{GUID} |
Required. This key contains the root entry for snap-in registry information. FX is a prefix that is used to distinguish MMC 3.0 snap-ins from the older snap-ins. |
FX:{GUID}/Namestring |
Optional. This REG_SZ value specifies the un-localized name of the snap-in. In the absence of a localized name, this value is used in the Add/Remove Snap-in dialog box. |
FX:{GUID}/Description |
Optional. This REG_SZ value specifies the un-localized description of the snap-in. In the absence of a localized description, this value is used in the Add/Remove Snap-in dialog box. |
FX:{GUID}/Version |
Optional. This REG_SZ value specifies the un-localized version of the snap-in. In the absence of a localized version, this value is used in the Add/Remove Snap-in dialog box. |
FX:{GUID}/Provider |
Optional. This REG_SZ value specifies the un-localized vendor name of the snap-in. If a localized version of the provider does not exist, this value is used in the Add/Remove Snap-in dialog box. |
FX:{GUID}/ApplicationBase |
Required. This REG_SZ value specifies the base directory for the assembly that contains the snap-in. Configuration files and other files that are associated with the snap-in are referenced in relation to this path. |
FX:{GUID}/ModuleName |
Required. This REG_SZ value specifies the name of the module that contains the snap-in. |
FX:{GUID}/About |
Required. This REG_SZ value specifies the CLSID for the COM object that implements ISnapInAbout interface. This value is not used for managed snap-ins, so it is always initialized to all zeros. |
FX:{GUID}/RuntimeVersion |
Required. This REG_SZ value specifies the version of the common language runtime (CLR) that the snap-in was built against. |
FX:{GUID}/ConfigurationFile |
Optional. This REG_SZ value specifies the configuration file to use for the snap-in. If this value is not present, a default configuration file in the form of <assemblyname>.dll.config is used. |
FX:{GUID}/LicenseFile |
Optional. This REG_SZ value specifies the license file to use for the snap-in. |
FX:{GUID}/Standalone |
This is a key that is required if the snap-in is a primary snap-in. This key notifies MMC that the snap-in is a stand-alone snap-in, as opposed to an extension. |
FX:{GUID}/Extension |
This is a key that is required if the snap-in is a snap-in extension. This key notifies MMC that the snap-in is an extension snap-in. The default value is one of: Namespace, PropertySheet. |
FX:{GUID}/NodeTypes |
Optional. This key has sub keys that represent nodes that are published by the snap-in. This key might not be present if no nodes are published. |
FX:{GUID}/NodeTypes/{GUID} |
Optional. This key specifies a node type (in the form of a GUID) that is published by the snap-in. There may be 0 or more {GUID} keys under this key. |
SnapInAboutAttribute
Snap-ins may choose to provide localized SnapInAboutAttribute information instead of, or in addition to, providing un-localized strings. This information is used in the Add/Remove Snap-In dialog in core MMC. If a snap-in has a SnapInAboutAttribute applied to it, the following registry keys and values may exist. Each entry that refers to an indirect resource uses the format “@[path\]<dllname>,-<id>”, where path is the path to the module, <dllname> is the module file name, and <id> is the native resource Id within the module.
InstallUtil.exe populates the SnapInAbout registry entries for a given snap-in under HKLM/Software/Microsoft/MMC/NodeTypes/FX:{GUID}.
Path |
Description |
ModuleName |
Required. This REG_SZ value specifies the module that contains the unmanaged resources for the SnapInAbout information. |
DescriptionStringIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the snap-in description. |
NamestringIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the name of the snap-in. |
ProviderStringIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the snap-in provider. |
VersionStringIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the snap-in version. |
IconIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the description of the snap-in. |
LargeFolderBitmapIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the large folder bitmap of the snap-in. The bitmap is 32x32 with 256 colors using the System palette. |
SmallFolderBitmapIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the small folder bitmap of the snap-in. The bitmap is 16x16 with 256 colors using the System palette. |
SmallSelectedFolderBitmapIndirect |
Optional. This REG_SZ value specifies the localized resource ID for the small selected folder bitmap of the snap-in. The bitmap is 16x16 with 256 colors using the System palette. |
SnapInLinkedHelpTopicAttribute
This optional attribute specifies a linked Help topic that is associated with a snap-in. At runtime, MMC uses the information in the attributes to find and load the referenced .chm files. You can also use the attribute to call the help topic for a scope node. You can also specify the help topic on the selection data and property page objects.
SnapInHelpTopicAttribute
This optional attribute specifies the Help file and topic associated with a snap-in. An
ApplicationBaseRelative property of this attribute indicates whether the Help path is relative to the snap-in application base.
RunInstaller Attribute
SnapInInstaller is the base class for snap-in registration. It utilizes reflection to search for snap-ins that are defined within the currently loaded assembly. This metadata is then used to populate or remove register entries as appropriate for each snap-in. For each assembly in which a snap-in is defined and must be registered, a derivation of this class must exist with the RunInstaller attribute set to true. The derived class may be empty and may not override any of the virtual methods, or it may override them to provide additional registration functionality. The class that is derived from SnapInInstaller provides an entry point for tools such as InstallUtil.exe.
Scope Node
The ScopeNode class provides the basic icon and name for a node in the tree pane. Child nodes can also be added to a scope node and are shown indented underneath their parent node in the tree pane. Child nodes can also be added just-in-time by programming the OnExpand method that gets called when the plus sign next to the node is clicked.
Multiple view descriptions can be added to a scope node to define more detailed views in the results pane when the scope node is selected. The default view for a scope node shows its children.
The ScopeNode class inherits from the Node class, which provides functionality that is common to all node types. This includes actions, display text, node types, and changed events. The ScopeNode class adds specialization for nodes that represent items in the MMC scope namespace. The scope namespace is hierarchical, so scope nodes have Children. Each scope node may have a set of associated ViewDescriptions. Each view description may define zero or more view types using the ViewType property. The view description collection has a DefaultIndex that determines which view is shown when the node is selected. Child nodes are listed to provide the default view for a scope node if no view descriptions are provided. The ViewDescription class only provides the characteristics of a view. When a scope node gets selected, MMC uses the view descriptions to create the view.
SPECIAL NOTE:
As you design a snap-in, remember that MMC is an MDI application and that it is possible that many child windows are opened simultaneously. Although the tree pane, results pane and actions pane may be visible in each window, only the Results pane and the actions pane are unique to the window. The tree pane may be shared by several windows, and therefore should not be considered window-specific.
There are several implications of this:
There is no concept of focus for a scope node.
Scope nodes should truly be used for scoping and not for abstracting leaf items. For example, a snap-in that displays an event log could have child scope nodes that are used to filter events based on the source of the event, such as, application, security, or system events. However, the actual list of events that correspond to the leaf nodes must appear in the results pane.
There is no assigned list of views for a scope node. MMC creates the views as needed, using view descriptions.
Views should be architected so that they are not dependent on the state of the scope node.
Result Node
Unlike scope nodes, result nodes cannot have children. They are used solely to populate an instance of MmcListView. By default, the MMC list view displays a name and an icon for the result node. It can also display the values from a SubItemDisplayNames collection of a result node in additional columns defined by the list view (when the list is shown in the report mode).
Actions
When the action that is desired is not in the list of Standard Verbs, then a custom action can be created. Custom Actions will show in the context menu and in the actions pane.
In MMC 3.0, you can add actions to the actions pane and to the context menus, by defining actions on nodes, and views and selected items within views. The snap-in has the ability to set properties on the actions to indicate enabled/disabled and checked/cleared states as well as radio button selection states.
Three types of actions can be defined:
Actions on Nodes:
These are actions that execute against the node as an object. These actions appear in the node (top) section of the actions pane and are duplicated in the context menu of the node in the tree. The node must handle these actions.
Actions on Views:
These are actions that execute against a view, or on the collection of items in the view. This includes actions such as “filter items”, “add new item”, and “update all”. These actions appear in the node (top) section of the actions pane, beneath the actions on nodes. They are duplicated in the context menu of the selected node in the tree, and are also in the background context menu of the view. Unlike actions on nodes, actions on views will not appear in the scope node's context menu if the scope node is not selected. The view is responsible for handling the user selection of these actions.
Actions on Selected Items in View:
These are actions that execute against one or more items selected in the view. These actions appear in the item (bottom) section of the actions pane and are duplicated in the context menu of the selected items in the view.
Standard Verbs
Standard verbs can be set for both scope nodes and the selected items in a view to handle the most common actions such as a Refresh. Setting the EnabledStandardVerbs property for a scope node or for the selection data automatically adds the standard verbs to the context menus and actions pane. Each standard verb has a specific handler for when it is clicked. Standard verbs can be enabled and disabled by the snap-in. There are two sets of standard verbs, those that pertain to the node and those that pertain to the selected object in the view. The list of standard verbs that are supported in MMC 3.0 is as follows:
Copy
Paste
Delete
Properties
Rename
Refresh
Print
Cut
Views and View Descriptions
Each scope node has an associated view descriptions collection. The default index determines which view is shown when the node is selected initially. By default, a list view that displays the child nodes of the scope node is presented if no view descriptions are provided for the scope node.
The ViewDescription class only provides a definition of the view to be shown. To avoid unnecessary processing at load time, MMC uses the view descriptions to create the view when the scope node is selected. There are four kinds of views. Each view has its own view description that MMC uses to create the appropriate view when required. The MmcListView can be used to show a list of result nodes in the results pane. It supports small icons, large icons, lists, and report views, multi-select and single select, and multiple columns with sorting by column.
FormView can be used to embed a Windows Forms form in the results pane. This view is used when a scope node requires a different view that just a list of managed objects. The form view allows complete control over the results pane, but can still support the actions pane and context menu features of MMC by updating the selection data using the selection data object.
HtmlView is used to show a webpage in the results pane. The URL for the webpage to be displayed is specified by the view description when it is defined and used to populate the results pane when the scope node is selected.
MessageView is used to provide a standard MMC message view. It allows the result pane to be populated with a title, body text, and one of many predefined icons.
Using Selection Data
It is useful to understand the concept of selection data while designing your views. The selection data does not directly correspond to a user interface object. It provides a consistent API for manipulating the selected items in a view as the set changes with user action, irrespective of whether the selection is in a list view or a form view, and regardless of whether it is a single selection or a multi-selection. Selection data is used to provide information about the selection in list views and form views. This includes actions, standard verbs, node types, and shared data.
A single instance of selection data that corresponds to each view instance is always available to the snap-in. When a selection changes, if the snap-in determines that no items are selected, it must call Clear. It must call Update when one or more items are selected. The Clear method automatically clears the unique node types and shared data for selection, but does not clear other properties, which must be cleared explicitly if needed. Note that neither the Clear nor the Update methods clear or change any standard verbs or actions that may have been previously set. Selection data is used to identify a selection in list views and form views so that MMC can update the context menus, actions, action description, and shared data.
An object called the selection object is passed as the first parameter to the update method. The selection object can be any object that is used to uniquely identify the selection. For the same set of data items, the snap-in must always provide selection objects that are equal. Whether two selection objects are equal is determined by MMC using the IComparable.CompareTo method (if the selection object implements System.IComparable) or by a reference comparison (if the selection object does not implement System.IComparable).
Often times, it is useful to construct such an object by combining unique identifiers of multiple items in the snap-in that are part of the selection. An example of a selection object for a view that shows a list of employees would be a collection of employee Ids for the selected items in the list.
The selection object is the first parameter to the Update method. An example of a selection object for a view that shows a list of employees, would be a string built from the employee Ids of the selected items in the list. This unique identifier allows MMC to recognize whether the selection is in use. For example, a property sheet may have already been opened for the selection, so MMC would bring the same in focus.
MMC uses the selection object for two broad purposes:
First, to help the framework determine if the data that is represented by one selection is the same as the data that is represented by another selection (in a different view or in the same view at a different time). When the user selects the Properties verb for a view selection, a property sheet may already be open for a selection that represents the same data. MMC compares the selection object for the open property sheet to the current selection to determine if the existing sheet should be brought to the foreground or whether a new instance needs to be created. Another example of the use of selection objects is to show a long running action as disabled in all views where the current selection represents the same data as a previous selection.
Second, to pass as a parameter to callback methods (such as OnPaste, OnGetSharedData) that can be invoked long after the original selection has changed.
Utility Programs
The following programs and classes are used during snap-in creation and installation.
InstallUtil.exe: A command-line tool for installing managed applications. Installutil.exe uses reflection to inspect the specified assembly and find all Installer types with the RunInstallerAttribute set to true. The tool then executes either the Install Method or the Uninstall Method on each instance of the Installer type. For more information about InstallUtil.exe see Installer Tool (Installutil.exe).
SnapInInstaller: Installers are components that help install applications on a computer. The SnapInInstaller class derives from Installer.
Property Sheets and Pages
MMC provides the ability to create property sheets based on Win32 property pages. Developers can derive from the PropertyPage class to create property pages based on a Windows Forms control. It provides methods for handling notifications with default implementations and for manipulating the parent property sheet. The PropertySheet class is an abstraction of a Win32 property sheet common control. It is a collection of property pages with title and style information.
Wizards
A wizard is a special type of property sheet that provides a simple and powerful way to guide users through complex procedures. Wizards are designed to present pages one at a time in a sequence that is controlled by the application. Instead of selecting from a group of pages by clicking a tab, users move forward and backward through the sequence, one page at a time, by clicking Next or Back buttons that are located at the bottom of the wizard. Here are some useful points about wizards and property sheets:
The snap-in developer is free to use any UI derived from System.Windows.Forms.Control.
Property sheets are created on a secondary MMC thread and are not modal with respect to MMC. On the other hand, wizards are created on the main MMC thread and are modal.
Property sheets and wizards are always modal to the thread they are created on.
Wizard property sheets are not extendable.
Dialogs
A dialog is a special purpose user interface that is typically used for handling standard verbs and custom actions. Dialogs must be displayed on the snap-in thread that created them.
There are four types of dialogs:
Common dialog: This is a dialog that is derived from the CommonDialog class. Examples of dialogs include the Color Picker dialog and the File Open dialog.
MessageBox: This dialog that pops up a message box. A MessageBoxParameters object is a structure that contains all the properties that would normally be set or passed directly to the MessageBox. This group of settings is then used by MMC to show the final MessageBox.
User-defined dialog: This dialog is a form that is derived from a Windows Forms form. A User-defined dialog should provide for a result to be passed back to the calling code.
User-defined dialog with a wait cursor: This dialog is a form that is derived from a Windows Forms form with an additional wait cursor object to suppress the display of the form until the wait cursor duration expires. The wait cursor can be used to cause the dialog to be displayed only after a certain amount of time has passed. The typical use of this approach is to provide a dialog to abort out of a long running task. The dialog may never be shown if the task completes quickly enough and the wait cursor is informed that the task is complete.
Localization
This is a brief note on localization of a snap-in or namespace extension for the Add/Remove Snap-in dialog. MMC uses information in the registry to display the snap-in name, description and icon for snap-ins in the list. In order to support using an external resource file at Add / Remove, you must include a SnapInAboutAttribute attribute on the snap-in class. This attribute identifies the external resource file to use. The following snippet shows how the localization can be done. For a detailed example, visit <MMC 3.0 Samples>\LocalizedRegistrationSample. It shows how to localize the snap-in registration. It contains two projects. The first defines a new resource.dll. The second uses the SnapInAboutAttribute attribute to define resources in the external dll that are used to register the snap-in.
Threading
An advanced developer who is proficient with threading may consider improving the performance of a snap-in that contains a long running task by using threads.
In general, threading considerations for a snap-in are handled by MMC. Note: To update the user interface, the snap-in thread must be used. Other threads may run delegates on the snap-in thread using BeginInvoke. For a detailed example of a snap-in that uses its own threading visit <MMC 3.0 Samples>\ThreadingSample. It shows how use a separate thread to expand nodes and update the status and progress bar. It defines a new type of ScopeNode that adds children to itself. It creates a new thread to perform the addition. The new thread uses Invoke method to create a delegate to add the nodes.
Checklist for Snap-in Design and Development
Use newly created GUIDs for all of your snap-ins, node types, and namespace extensions.
Expose a unique identifier for each result node in your snap-in.
Implement a standard verb instead of creating a custom action with the same name.
Code that references other objects should be placed in the respective PropertyPage.OnInitialize or View.OnInitialize methods instead of in object constructors.
Ensure that actions are localized in terms of text and that handling is not reliant on any text that could be localized.
Update the selection data object when the selection changes and then use the selection object to get the current selection when you handle a standard verb or action.
Add columns to an MMC list view by using AddRange.
Add result nodes to an MMC list view by using AddRange
Design your property sheets such that the user is encouraged to finish with the property sheet before clicking anywhere else.
Create common actions once and add the same action to a large group of nodes.
Use the ShowDialog method to show modal dialogs.
Use the MessageBoxParameters object to display a message box instead of directly instantiating it.
Create a binary table of contents for your help files.
Reinstall the snap-in using InstallUtil.exe each time any of SnapInSettingsAttribute, SnapInAboutAttribute, SnapInHelpTopicAttribute, or SnapInLinkedHelpTopicAttribute is changed.
Do not directly extend the Computer Management snap-in or add a direct child to its scope node. Instead, extend one of its existing child nodes such as the System Tools node.
Do use Unicode strings when passing shared data between snap-ins and namespace extensions.
Ship and install both 64-bit and 32-bit versions of your snap-ins.
Do not block a thread or put a thread to sleep.
Do not forget to check the behavior of your snap-in when multiple MDI child windows are open.
See Also
Microsoft.ManagementConsole
Microsoft.ManagementConsole.Advanced
MMC Technology Summary