Define All Required GUID Values

A minimum of two GUID values must be generated to support extending the Applications snap-in base property page, a property sheet extension GUID, and an extid attribute.

Be aware of the following GUID values:

A code example section follows the description of all necessary GUID definitions at the end of this topic.

Note

In the following sections, the term, "snap-in extension", refers to what had been called "plug-in" in earlier versions of the documentation. In some sections of the code comments, you may still find references to plug-in to mean the same as "snap-in extension."

 

When discussing the extension of the Applications snap-in, a single GUID may be expressed in four formats.

For more information about how to generate a GUID in a specific format using the Guidgen.exe tool, see the MSDN topic GUIDGEN Sample: Generates Globally Unique Identifiers (GUIDs).

Applications snap-in result pane GUID

To extend the property sheet of the Applications extendable node type, a snap-in (sometimes also called a plug-in) must register its property sheet extension to extend the following node GUID: "{C8535E2E-148D-494d-8E9A-71FC46649B5E}".

[!Important]
You must use this GUID, as is, to extend the Applications node type for the Group Policy preference extension.

 

Property sheet extension GUID

The property sheet extension GUID uniquely identifies the snap-in (sometimes called a plug-in) to the Microsoft Management Console (MMC) that represents the {CLSID} of the extension snap-in.

The property sheet extension GUID must be registered:

  • under the HKEY_CLASSES_ROOT\CLSID key in the {CLSID} subkey as an in-process server DLL. The snap-in must also register a threading model for the snap-in CLSID. An apartment threading model is recommended.

    For more information about the HKEY_CLASSES_ROOT\CLSID key, see the CLSID Key topic in the Microsoft Windows Software Development Kit (SDK). For more information and a code example, see Registering and Unregistering a Snap-in.

  • under the HKEY_LOCAL_MACHINE\Software\Microsoft\MMC\NodeTypes\{nodetypeGUID}\Extensions\PropertySheet subkey, where "nodetypeGUID" is the node type GUID of the node type whose property sheet is extended. For more information about the NodeTypes key, see Registration Requirements for Extension Snap-ins.

[!Important]
When defined, do not change or remove the property sheet extension GUID. This value should not be changed or removed prior to unregistering the snap-in. This is an unsupported operation and could cause unexpected behavior.

 

extid Attribute (GUID)

After a snap-in is extended by a functional property sheet extension, all instances of that snap-in will display all new property page(s) that are incorporated. Restricting the presentation of the extension pages to the appropriate context is the responsibility of each snap-in property page extension.

The Extension ID or extid Attribute GUID uniquely identifies the snap-in property page extension relative to the Applications snap-in. In the code examples provided with this section you must replace the sample extid GUID with a new GUID value.

[!Important]
Do not change or remove a defined extid attribute. This value should not be changed or removed prior to unregistering the snap-in. This is an unsupported operation and could cause unexpected behavior.

 

snap-in about interface GUID

When About is selected from the Help menu in the MMC, the Group Policy preference snap-in About dialog box is displayed instead of the one defined by the Applications property sheet extension. Despite the fact that this interface is superseded by the Group Policy preference snap-in, you should change this GUID to prevent conflicts with other property sheet extensions. The code example provided at the end of this topic includes the definition of the snap-in about GUID.

Code Examples

The following code examples define the four GUID values.

The first code example provides a sample header file to define the two GUID values you must generate and the optional value for the Help About value. This code is included in the downloadable full code example in the "Guids.h" file.

Note

Any comment in the following code example that starts with "TODO:" refers to an action that you must perform when modifying the code for a new extension to the property sheets for the Applications snap-in. Comments that do not start with "TODO:" describe an action that the subsequent code will perform.

 

// TODO: Generate a GUID for use as this plug-in "Extension ID" ("extid"): 
//       Place it here and in Registry.cpp:
const WCHAR g_szwExtId[] = L"{5F6A652F-1FA2-4A5C-B4DB-48D5D8095F47}";

// TODO: Generate a GUID for this plug-in, 
//       place it here and in Registry.cpp:

// {A2E38A7B-D9B2-4DFC-8569-1F5383061590}
DEFINE_GUID( CLSID_CPropSheetExtension, 
   0xA2E38A7B, 0xD9B2, 0x4DFC, 0x85, 0x69, 0x1F, 0x53, 0x83, 0x06, 0x15, 0x90 );


// TODO: Generate a GUID for snap-in About interface, 

// {E8072002-F374-471e-98AC-93F24D36752C}
DEFINE_GUID( CLSID_CSnapinAbout, 
   0xE8072002, 0xF374, 0x471E, 0x98, 0xAC, 0x93, 0xF2, 0x4D, 0x36, 0x75, 0x2C );

The second example provides the GUID values mapping the Applications extendable node type to the snap-in (or plug-in) that will extend the Applications node. This code is included in the downloadable full sample in the file,"Registry.cpp".

Note

Any comment in the following code example that starts with "TODO:" refers to an action that you must perform when modifying the code for a new extension to the property sheets for the Applications snap-in. Comments that do not start with "TODO:" describe an action that the subsequent code will perform.

 

// List all extended nodes.
// Applications Result Node {C8535E2E-148D-494D-8E9A-71FC46649B5E}

EXTENDER_NODE _NodeExtensions[] = {
    { PropertySheetExtension,
    // GUID of the node that this plug-in extends (must match value for Applications Result Node):
    { 0xC8535E2E, 0x148d, 0x494d, { 0x8e, 0x9a, 0x71, 0xfc, 0x46, 0x64, 0x9b, 0x5e } },
    // The plug-in GUID (must match value defined in Guids.h, CLSID_CPropSheetExtension):
    { 0xA2E38A7B, 0xD9B2, 0x4DFC, { 0x85, 0x69, 0x1F, 0x53, 0x83, 0x06, 0x15, 0x90 } },
    // Plug-in UID name:
    _T( "<<PLUGIN_NAME>>" ) },

    { DummyExtension,
      NULL,
      NULL,
      NULL }
};

The third example provides the helper functions for registering the extension with the Group Policy preferences snap-in and registering the extension as a component in the registry. This code is included in the downloadable full code example in the file,"Registry.cpp".

Note

Any comment in the following code example that starts with "TODO:" refers to an action that you must perform when modifying the code for a new extension to the property sheets for the Applications snap-in. Comments that do not start with "TODO:" describe an action that the subsequent code will perform.

 

/////////////////////////////////////////////////////////
//
// Public function implementation
//

//
// Register the plug-in with the Microsoft Group Policy Preferences snap-In:
//
LRESULT RegisterPlugin()
{
   HKEY hKey;

   // TODO: Replace "<<APPLICATION_NAME>>" with appropriate text:
   const TCHAR szKeyPath[] = _T( "SOFTWARE\\Microsoft" )
      _T( "\\Plugins\\Applications\\<<APPLICATION_NAME>>" );

   // TODO: Replace "<<PLUGIN_NAME>>" with appropriate text:
   const TCHAR szPluginName[] = _T( "<<PLUGIN_NAME>>" );

   // TODO: Replace this with the plug-in extid (defined in Guids.h, g_szwExtId):
   const TCHAR szExtId[] = _T( "{5F6A652F-1FA2-4A5C-B4DB-48D5D8095F47}" );

   // TODO: Replace this with the snap-in GUID (defined in Guids.h, CLSID_CPropSheetExtension):
   const TCHAR szSnapin[] = _T( "{A2E38A7B-D9B2-4dfc-8569-1F5383061590}" );

   // Create and open key and subkey.
   LRESULT lr = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKeyPath, 0, NULL, 
      REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &amp;hKey, NULL ) ;
   
   if ( lr == ERROR_SUCCESS )
   {
      lr = RegSetValueEx( hKey, _T( "" ), 0, REG_SZ, 
         (BYTE*)szPluginName,
         (DWORD)( _tcslen( szPluginName ) + 1 ) * sizeof( TCHAR ) );
      
      if ( lr == ERROR_SUCCESS )
      {
         lr = RegSetValueEx( hKey, _T( "ExtId" ), 0, REG_SZ, 
            (BYTE*)szExtId,
            (DWORD)( _tcslen( szExtId ) + 1 ) * sizeof( TCHAR ) );
      }

      if ( lr == ERROR_SUCCESS )
      {
         lr = RegSetValueEx( hKey, _T( "Snapin" ), 0, REG_SZ, 
            (BYTE*)szSnapin,
            (DWORD)( _tcslen( szSnapin ) + 1 ) * sizeof( TCHAR ) );
      }

      RegCloseKey( hKey );
   }
   
   return lr;
}

//
// Register the component in the registry.
//
HRESULT RegisterServer(HMODULE hModule,            // DLL module handle
                       const CLSID&amp; clsid,         // Class ID
                       const _TCHAR* szFriendlyName)       //   IDs
{
    // Get the server location.
    _TCHAR szModule[512] ;
    DWORD dwResult =
        ::GetModuleFileName(hModule,
        szModule,
        sizeof(szModule)/sizeof(_TCHAR)) ;

    assert(dwResult != 0) ;

    // Get the CLSID.
    LPOLESTR wszCLSID = NULL ;
    HRESULT hr = StringFromCLSID(clsid, &amp;wszCLSID) ;

    assert(SUCCEEDED(hr)) ;

    MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);

    // Build the key CLSID\\{...}
    _TCHAR szKey[64] ;
    _tcscpy_s(szKey, _countof(szKey), _T("CLSID\\")) ;
    _tcscat_s(szKey, _countof(szKey), pszCLSID) ;

    // Add the CLSID to the registry.
    setKeyAndValue(szKey, NULL, szFriendlyName) ;

    // Add the server filename subkey under the CLSID key.
    setKeyAndValue(szKey, _T("InprocServer32"), szModule) ;

    // Set the threading model
    _tcscat_s(szKey, _countof(szKey), _T("\\InprocServer32"));
    setValue(szKey, _T("ThreadingModel"), _T("Apartment"));

    // Free the memory.
    CoTaskMemFree(wszCLSID);
    
    // Register the plug-in with the Microsoft Group Policy Preferences snap-In:
    /* LRESULT */ RegisterPlugin();

    return S_OK ;
}