Creación de controladores de extensiones de shell
Las funcionalidades del Shell se pueden ampliar con entradas del Registro y archivos .ini. Aunque este enfoque para extender el Shell es sencillo y adecuado para muchos propósitos, es limitado. Por ejemplo, si usa el Registro para especificar un icono personalizado para un tipo de archivo, aparecerá el mismo icono para cada archivo de ese tipo. La extensión del shell con el registro no permite variar el icono de archivos diferentes del mismo tipo. Otros aspectos del Shell, como la hoja de propiedades Propiedades que se puede mostrar cuando se hace clic con el botón derecho en un archivo, no se pueden modificar en absoluto con el Registro.
Un enfoque más eficaz y flexible para extender el shell es implementar controladores de extensión de shell. Estos controladores se pueden implementar para una variedad de acciones que el Shell puede realizar. Antes de realizar la acción, shell consulta el controlador de extensión, lo que le da la oportunidad de modificar la acción. Un ejemplo común es un controlador de extensión de menú contextual. Si se implementa uno para un tipo de archivo, se consultará cada vez que se haga clic con el botón derecho en uno de los archivos. Después, el controlador puede especificar elementos de menú adicionales en un archivo por archivo, en lugar de tener el mismo conjunto para todo el tipo de archivo.
En este documento se describe cómo implementar los controladores de extensión que permiten modificar una variedad de acciones de Shell. Los siguientes controladores están asociados a un tipo de archivo determinado y le permiten especificar en un archivo por archivo:
Controlador | Descripción |
---|---|
Controlador de menú contextual | Se llama antes de que se muestre el menú contextual de un archivo. Permite agregar elementos al menú contextual en un archivo por archivo. |
Controlador de datos | Se llama cuando se realiza una operación de arrastrar y colocar en objetos de ArrastrarShell. Permite proporcionar formatos adicionales del Portapapeles al destino de colocación. |
Controlador de colocación | Se llama cuando un objeto de datos se arrastra o se coloca en un archivo. Permite convertir un archivo en un destino de colocación. |
Controlador de iconos | Se llama antes de que se muestre el icono de un archivo. Permite reemplazar el icono predeterminado del archivo por un icono personalizado en un archivo por archivo. |
Controlador de la hoja de propiedades | Se llama antes de que se muestre la hoja de propiedades Properties de un objeto. Permite agregar o reemplazar páginas. |
Controlador de imágenes en miniatura | Proporciona una imagen para representar el elemento. |
Controlador de recuadro informativo | Proporciona texto emergente cuando el usuario mantiene el puntero del mouse sobre el objeto. |
Controlador de metadatos | Proporciona acceso de lectura y escritura a metadatos (propiedades) almacenados en un archivo. Esto se puede usar para ampliar la vista Detalles, la información sobre información, la página de propiedades y las características de agrupación. |
Otros controladores no están asociados a un tipo de archivo determinado, pero se llaman antes de algunas operaciones de Shell:
Controlador | Descripción |
---|---|
Controlador de columnas | Lo llama el Explorador de Windows antes de mostrar la vista Detalles de una carpeta. Permite agregar columnas personalizadas a la vista Detalles. |
Controlador de enlace de copia | Se llama cuando se va a mover, copiar, eliminar o cambiar el nombre de un objeto de carpeta o impresora. Le permite aprobar o vetar la operación. |
Controlador de arrastrar y colocar | Se llama cuando se arrastra un archivo con el botón derecho del mouse. Permite modificar el menú contextual que se muestra. |
Icono Controlador de superposición | Se llama antes de que se muestre el icono de un archivo. Permite especificar una superposición para el icono del archivo. |
Controlador de búsqueda | Se llama para iniciar un motor de búsqueda. Permite implementar un motor de búsqueda personalizado accesible desde el menú Inicio o el Explorador de Windows. |
Los detalles de cómo implementar controladores de extensión específicos se tratan en las secciones enumeradas anteriormente. En el resto de este documento se tratan algunos problemas de implementación que son comunes a todos los controladores de extensión de Shell.
- Implementación de controladores de extensión de Shell
- Mejora de la búsqueda de Windows con controladores de extensión de Shell
- Registro de controladores de extensiones de shell
- Temas relacionados
Gran parte de la implementación de un objeto de controlador de extensiones de Shell depende de su tipo. Sin embargo, hay algunos elementos comunes. En esta sección se describen los aspectos de la implementación que comparten todos los controladores de extensión de Shell.
Muchos controladores de extensión de Shell son objetos del modelo de objetos componentes (COM) en proceso. Se deben asignar un GUID y registrarse como se describe en Registro de controladores de extensión de shell. Se implementan como archivos DLL y deben exportar las siguientes funciones estándar:
- DllMain. Punto de entrada estándar al archivo DLL.
- DllGetClassObject. Expone el generador de clases del objeto.
- DllCanUnloadNow. COM llama a esta función para determinar si el objeto está atendiendo a cualquier cliente. Si no es así, el sistema puede descargar el archivo DLL y liberar la memoria asociada.
Al igual que todos los objetos COM, los controladores de extensión de Shell deben implementar una interfaz IUnknown y un generador de clases. La mayoría de los controladores de extensión también deben implementar una interfaz IPersistFile o IShellExtInit en Windows XP o versiones anteriores. Estos se reemplazaron por IInitializeWithStream, IInitializeWithItem e IInitializeWithFile en Windows Vista. El Shell usa estas interfaces para inicializar el controlador.
La interfaz IPersistFile debe implementarse mediante lo siguiente:
- Controladores de datos
- Controladores de colocación
En el pasado, también se necesitaban controladores de iconos para implementar IPersistFile, pero esto ya no es cierto. En el caso de los controladores de iconos, IPersistFile ahora es opcional y se prefieren otras interfaces como IInitializeWithItem .
La interfaz IShellExtInit debe implementarse mediante lo siguiente:
- Controladores de menú contextual
- Controladores de arrastrar y colocar
- Controladores de hoja de propiedades
La interfaz IPersistFile está pensada para permitir que un objeto se cargue o se guarde en un archivo de disco. Tiene seis métodos además de IUnknown, cinco propios, y el método GetClassID que hereda de IPersist. Con las extensiones de Shell, IPersist solo se usa para inicializar un objeto de controlador de extensión de Shell. Dado que normalmente no es necesario leer ni escribir en el disco, solo los métodos GetClassID y Load requieren una implementación que no sea de seguridad.
El shell llama primero a GetClassID y la función devuelve el identificador de clase (CLSID) del objeto de controlador de extensión. A continuación, shell llama a Load y pasa dos valores. El primero, pszFileName, es una cadena Unicode con el nombre del archivo o la carpeta en la que shell está a punto de funcionar. El segundo es dwMode, que indica el modo de acceso a archivos. Dado que normalmente no es necesario tener acceso a los archivos, dwMode suele ser cero. El método almacena estos valores según sea necesario para una referencia posterior.
En el fragmento de código siguiente se muestra cómo un controlador de extensión de Shell típico implementa los métodos GetClassID y Load . Está diseñado para controlar ANSI o Unicode. CLSID_SampleExtHandler es el GUID del objeto de controlador de extensión y CSampleExtHandler es el nombre de la clase utilizada para implementar la interfaz. Las variables m_szFileName y m_dwMode son variables privadas que se usan para almacenar el nombre y las marcas de acceso del archivo.
wchar_t m_szFileName[MAX_PATH]; // The file name
DWORD m_dwMode; // The file access mode
CSampleExtHandler::GetClassID(CLSID *pCLSID)
{
*pCLSID = CLSID_SampleExtHandler;
}
CSampleExtHandler::Load(PCWSTR pszFile, DWORD dwMode)
{
m_dwMode = dwMode;
return StringCchCopy(_szFileName, ARRAYSIZE(m_szFileName), pszFile);
}
La interfaz IShellExtInit solo tiene un método, IShellExtInit::Initialize, además de IUnknown. El método tiene tres parámetros que el Shell puede usar para pasar varios tipos de información. Los valores pasados dependen del tipo de controlador y algunos se pueden establecer en NULL.
- pIDFolder contiene el puntero de una carpeta a una lista de identificadores de elemento (PIDL). Para las extensiones de hoja de propiedades, es NULL. Para las extensiones de menú contextual, es el PIDL de la carpeta que contiene el elemento cuyo menú contextual se muestra. En el caso de los controladores de arrastrar y colocar no predeterminados, es el PIDL de la carpeta de destino.
- pDataObject contiene un puntero a la interfaz IDataObject de un objeto de datos. El objeto de datos contiene uno o varios nombres de archivo en formato CF_HDROP .
- hRegKey contiene una clave del Registro para el tipo de carpeta o objeto de archivo.
El método IShellExtInit::Initialize almacena el nombre de archivo, el puntero IDataObject y la clave del Registro según sea necesario para su uso posterior. En el fragmento de código siguiente se muestra una implementación de IShellExtInit::Initialize. Por motivos de simplicidad, en este ejemplo se supone que el objeto de datos contiene solo un único archivo. En general, puede contener varios archivos que deban extraerse cada uno.
LPCITEMIDLIST m_pIDFolder; //The folder's PIDL
wchar_t m_szFile[MAX_PATH]; //The file name
IDataObject *m_pDataObj; //The IDataObject pointer
HKEY m_hRegKey; //The file or folder's registry key
STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
IDataObject *pDataObj,
HKEY hRegKey)
{
// If Initialize has already been called, release the old PIDL
ILFree(m_pIDFolder);
m_pIDFolder = nullptr;
// Store the new PIDL.
if (pIDFolder)
{
m_pIDFolder = ILClone(pIDFolder);
}
// If Initialize has already been called, release the old
// IDataObject pointer.
if (m_pDataObj)
{
m_pDataObj->Release();
}
// If a data object pointer was passed in, save it and
// extract the file name.
if (pDataObj)
{
m_pDataObj = pDataObj;
pDataObj->AddRef();
STGMEDIUM medium;
FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
UINT uCount;
if (SUCCEEDED(m_pDataObj->GetData(&fe, &medium)))
{
// Get the count of files dropped.
uCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
// Get the first file name from the CF_HDROP.
if (uCount)
DragQueryFile((HDROP)medium.hGlobal, 0, m_szFile,
sizeof(m_szFile)/sizeof(TCHAR));
ReleaseStgMedium(&medium);
}
}
// Duplicate the registry handle.
if (hRegKey)
RegOpenKeyEx(hRegKey, nullptr, 0L, MAXIMUM_ALLOWED, &m_hRegKey);
return S_OK;
}
CSampleExtHandler es el nombre de la clase utilizada para implementar la interfaz . Las variables m_pIDFolder, m_pDataObject, m_szFileName y m_hRegKey son variables privadas que se usan para almacenar la información que se pasa. Por motivos de simplicidad, en este ejemplo se supone que solo el objeto de datos conservará un nombre de archivo. Después de recuperar la estructura FORMATETC del objeto de datos, DragQueryFile se usa para extraer el nombre de archivo del miembro medium.hGlobal de la estructura FORMATETC. Si se pasa una clave del Registro, el método usa RegOpenKeyEx para abrir la clave y asigna el identificador a m_hRegKey.
Hay dos maneras de personalizar la información sobre información:
- Implemente un objeto que admita IQueryInfo y, a continuación, registre ese objeto en la subclave adecuada en el Registro (vea Registrar controladores de extensiones de shell a continuación).
- Especifique una cadena fija o una lista de propiedades de archivo específicas que se mostrarán.
Para mostrar una cadena fija para una extensión de espacio de nombres, cree una entrada denominada InfoTip
en la clave {CLSID} de la extensión de espacio de nombres. Establezca el valor de esa entrada para que sea la cadena literal que desea mostrar, como se muestra en este ejemplo, o una cadena indirecta que especifica un recurso e índice dentro de ese recurso (con fines de localización).
HKEY_CLASSES_ROOT
CLSID
{CLSID}
InfoTip = InfoTip string for your namespace extension
Para mostrar una cadena fija para un tipo de archivo, cree una entrada denominada InfoTip
en la clave ProgID de ese tipo de archivo. Establezca el valor de esa entrada para que sea la cadena literal que desea mostrar o una cadena indirecta que especifique un recurso y un índice dentro de ese recurso (con fines de localización), como se muestra en este ejemplo.
HKEY_CLASSES_ROOT
ProgID
InfoTip = Resource.dll, 3
Si desea que el Shell muestre propiedades de archivo específicas en la información sobre un tipo de archivo específico, cree una entrada denominada InfoTip
en la clave ProgID para ese tipo de archivo. Establezca el valor de esa entrada para que sea una lista delimitadas por punto y coma de nombres de propiedad canónica, identificador de formato (FMTID)/pares de identificador de propiedad (PID) o ambos. Este valor debe comenzar por "prop:" para identificarlo como una cadena de lista de propiedades. Si omite "prop:", el valor se ve como una cadena literal y se muestra como tal.
En el ejemplo siguiente, propname es un nombre de propiedad canónico (como System.Date) y {fmtid},pid es un par FMTID/PID .
HKEY_CLASSES_ROOT
ProgID
InfoTip = prop:propname;propname;{fmtid},pid;{fmtid},pid
Se pueden usar los siguientes nombres de propiedad:
Nombre de propiedad | Descripción | Recuperado de |
---|---|---|
Autor | Autor del documento | PIDSI_AUTHOR |
Título | Título del documento | PIDSI_TITLE |
Asunto | Resumen del asunto | PIDSI_SUBJECT |
Comentario | Comentarios de documentos | propiedades de PIDSI_COMMENT o carpeta o controlador |
PageCount | Número de páginas | PIDSI_PAGECOUNT |
Nombre | Nombre descriptivo | Vista de carpeta estándar |
OriginalLocation | Ubicación del archivo original | Carpeta maletín y carpeta papelera de reciclaje |
DateDeleted | Se eliminó el archivo de fecha | Carpeta papelera de reciclaje |
Tipo | Tipo de archivo | Vista de detalles de carpeta estándar |
Size | Tamaño del archivo | Vista de detalles de carpeta estándar |
SyncCopyIn | Igual que OriginalLocation | Igual que OriginalLocation |
Modificado | Fecha de última modificación | Vista de detalles de carpeta estándar |
Creado | Fecha de creación | Vista de detalles de carpeta estándar |
Acceso | Fecha a la que se obtuvo acceso por última vez | Vista de detalles de carpeta estándar |
InFolder | Directorio que contiene el archivo | Resultados de la búsqueda de documentos |
Rank | Coincidencia de calidad de búsqueda | Resultados de la búsqueda de documentos |
FreeSpace | Espacio de almacenamiento disponible | Unidades de disco |
NumberOfVisits | Número de visitas | carpeta Favoritos |
Atributos | Atributos de archivo | Vista de detalles de carpeta estándar |
Compañía | Nombre de la compañía | PIDDSI_COMPANY |
Category | Categoría de documento | PIDDSI_CATEGORY |
Copyright | Derechos de autor de los medios | PIDMSI_COPYRIGHT |
HTMLInfoTipFile | Archivo de información sobre HTML | Desktop.ini archivo para la carpeta |
Los controladores de extensión de Shell se pueden usar para mejorar la experiencia del usuario proporcionada por un controlador de protocolo de Windows Search. Para habilitar estas mejoras, el controlador de extensión de Shell auxiliar debe diseñarse para integrarse con el controlador de protocolo de búsqueda como origen de datos. Para obtener información sobre cómo mejorar un controlador de protocolo de Búsqueda de Windows a través de la integración con un controlador de extensión de Shell, vea Agregar iconos, vistas previas y menús contextuales. Para obtener más información sobre los controladores de protocolos de Búsqueda de Windows, vea Desarrollar controladores de protocolo.
Se debe registrar un objeto de controlador de extensión de Shell para poder usarlo. Esta sección es una explicación general de cómo registrar un controlador de extensión de Shell.
Cada vez que cree o cambie un controlador de extensión de Shell, es importante notificar al sistema que ha realizado un cambio con SHChangeNotify, especificando el evento SHCNE_ASSOCCHANGED . Si no llama a SHChangeNotify, es posible que el cambio no se reconozca hasta que se reinicie el sistema.
Al igual que con todos los objetos COM, debe crear un GUID para el controlador mediante una herramienta como UUIDGEN.exe. Cree una clave en HKEY_CLASSES_ROOT\CLSID cuyo nombre sea la forma de cadena del GUID. Dado que los controladores de extensión de Shell son servidores en proceso, debe crear una clave InProcServer32 en la clave GUID con el valor predeterminado establecido en la ruta de acceso del archivo DLL del controlador. Use el modelo de subprocesos de apartamento.
Cada vez que el Shell realiza una acción que puede implicar un controlador de extensión de Shell, comprueba la clave del Registro adecuada. La clave con la que se registra un controlador de extensión controla por lo tanto cuándo se llamará. Por ejemplo, es una práctica habitual tener un controlador de menú contextual al que se llama cuando shell muestra un menú contextual para un miembro de un tipo de archivo. En este caso, el controlador debe estar registrado en la clave ProgID del tipo de archivo.
Para habilitar un controlador de extensión de Shell, cree una subclave con el nombre de subclave del controlador (vea a continuación) en la subclave ShellEx de ProgID (para tipos de archivo) o el nombre del tipo de objeto shell (para objetos shell predefinidos).
Por ejemplo, si desea registrar un controlador de extensión de menú contextual para MyProgram.1, empezaría creando la siguiente subclave:
HKEY_CLASSES_ROOT
MyProgram.1
ShellEx
ContextMenuHandlers
Para los siguientes controladores, cree una subclave debajo de la clave "Nombre de subclave del controlador" cuyo nombre es la versión de cadena del CLSID de la extensión shell. Se pueden registrar varias extensiones en la clave de nombre de subclave del controlador mediante la creación de varias subclaves.
Controlador | Interfaz | Nombre de subclave del controlador |
---|---|---|
Controlador de menú contextual | IContextMenu | ContextMenuHandlers |
Controlador de copyhook | ICopyHook | CopyHookHandlers |
Controlador de arrastrar y colocar | IContextMenu | DragDropHandlers |
Controlador de la hoja de propiedades | IShellPropSheetExt | PropertySheetHandlers |
Controlador de proveedor de columnas (en desuso en Windows Vista) | IColumnProvider | ColumnHandlers |
Para los siguientes controladores, el valor predeterminado de la clave "Nombre de subclave del controlador" es la versión de cadena del CLSID de la extensión shell. Solo se puede registrar una extensión para estos controladores.
Controlador | Interfaz | Nombre de subclave del controlador |
---|---|---|
Controlador de datos | IDataObject | Datahandler |
Controlador de colocación | IDropTarget | DropHandler |
Controlador de iconos | IExtractIconA/W | IconHandler |
Controlador de imágenes | IExtractImage | {BB2E617C-0920-11d1-9A0B-00C04FC2D6C1} |
Controlador de imágenes en miniatura | IThumbnailProvider | {E357FCCD-A995-4576-B01F-234630154E96} |
Controlador de recuadro informativo | IQueryInfo | {00021500-0000-0000-C000-000000000046} |
Vínculo de Shell (ANSI) | IShellLinkA | {000214EE-0000-0000-C000-000000000046} |
Vínculo de Shell (UNICODE) | IShellLinkW | {000214F9-0000-0000-C000-000000000046} |
Almacenamiento estructurado | IStorage | {0000000B-0000-0000-C0000-00000000046} |
Metadatos | IPropertyStore | PropertyHandler |
Metadatos | IPropertySetStorage (en desuso en Windows Vista) | PropertyHandler |
Anclar al menú Inicio | IStartMenuPinnedList | {a2a9545d-a0c2-42b4-9708-a0b2badd77c8} |
Anclar a la barra de tareas | {90AA3A4E-1CBA-4233-B8BB-535773D48449} |
Las subclaves especificadas para agregar Anclar al menú Inicio y Anclar a la barra de tareas al menú contextual de un elemento solo son necesarias para los tipos de archivo que incluyen la entrada IsShortCut .
Se quitó la compatibilidad con los controladores de proveedor de columnas en Windows Vista. Además, a partir de Windows Vista, IPropertySetStorage ha quedado en desuso en favor de IPropertyStore.
Aunque IExtractImage sigue siendo compatible, se prefiere IThumbnailProvider para Windows Vista y versiones posteriores.
El Shell define objetos adicionales en HKEY_CLASSES_ROOT que se pueden extender de la misma manera que los tipos de archivo. Por ejemplo, para agregar un controlador de hoja de propiedades para todos los archivos, puede registrarse en la clave PropertySheetHandlers .
HKEY_CLASSES_ROOT
*
shellex
PropertySheetHandlers
En la tabla siguiente se proporcionan las distintas subclaves de HKEY_CLASSES_ROOT en las que se pueden registrar controladores de extensión. Tenga en cuenta que muchos controladores de extensión no se pueden registrar en todas las subclaves enumeradas. Para obtener más información, consulte la documentación del controlador específico.
Subclave | Descripción | Posibles controladores | Versión |
---|---|---|---|
* | Todos los archivos | Menú contextual, Hoja de propiedades, Verbos (ver a continuación) | Todo |
AllFileSystemObjects | Todos los archivos y carpetas de archivos | Menú contextual, Hoja de propiedades, Verbos | 4.71 |
Carpeta | Todas las carpetas | Menú contextual, Hoja de propiedades, Verbos | Todo |
Directorio | Carpetas de archivos | Menú contextual, Hoja de propiedades, Verbos | Todo |
Directorio\Fondo | Fondo de la carpeta de archivos | Solo menú contextual | 4.71 |
Conducir | Todas las unidades de MyComputer, como "C:\" | Menú contextual, Hoja de propiedades, Verbos | Todo |
Network | Toda la red (en Mis sitios de red) | Menú contextual, Hoja de propiedades, Verbos | Todo |
Network\Type\ # | Todos los objetos de tipo # (consulte a continuación) | Menú contextual, Hoja de propiedades, Verbos | 4.71 |
NetShare | Todos los recursos compartidos de red | Menú contextual, Hoja de propiedades, Verbos | 4.71 |
Netserver | Todos los servidores de red | Menú contextual, Hoja de propiedades, Verbos | 4.71 |
network_provider_name | Todos los objetos proporcionados por el proveedor de red "network_provider_name" | Menú contextual, Hoja de propiedades, Verbos | Todo |
Impresoras | Todas las impresoras | Menú contextual, Hoja de propiedades | Todo |
AudioCD | CD de audio en la unidad de CD | Solo verbos | Todo |
DVD | Unidad de DVD (Windows 2000) | Menú contextual, Hoja de propiedades, Verbos | 4.71 |
Notas:
- Para acceder al menú contextual de fondo de la carpeta de archivos, haga clic con el botón derecho en una carpeta de archivos, pero no sobre ninguno de los contenidos de la carpeta.
- "Verbos" son comandos especiales registrados en HKEY_CLASSES_ROOT\Subclave\Shell\Verb .
- ParaTipo\#de red\ , "#" es un código de tipo de proveedor de red en decimal. El código de tipo de proveedor de red es la palabra alta de un tipo de red. La lista de tipos de red se da en el archivo de encabezado Winnetwk.h (valores WNNC_NET_*). Por ejemplo, WNNC_NET_SHIVA es 0x00330000, por lo que la clave de tipo correspondiente sería HKEY_CLASSES_ROOT\Tipo\ dered\51 .
- "network_provider_name" es un nombre de proveedor de red especificado por WNetGetProviderName, con los espacios convertidos en caracteres de subrayado. Por ejemplo, si está instalado el proveedor de red de redes de Microsoft, su nombre de proveedor es "Microsoft Windows Network" y el network_provider_name correspondiente es Microsoft_Windows_Network.
Para habilitar un controlador determinado, cree una subclave en la clave de tipo de controlador de extensión con el nombre del controlador. El Shell no usa el nombre del controlador, pero debe ser diferente de todos los demás nombres de esa subclave de tipo. Establezca el valor predeterminado de la subclave name en el formato de cadena del GUID del controlador.
En el ejemplo siguiente se muestran las entradas del Registro que habilitan los controladores de extensión de hoja de propiedades y menú contextual, mediante un tipo de archivo .myp de ejemplo:
HKEY_CLASSES_ROOT
.myp
(Default) = MyProgram.1
CLSID
{00000000-1111-2222-3333-444444444444}
InProcServer32
(Default) = C:\MyDir\MyCommand.dll
ThreadingModel = Apartment
{11111111-2222-3333-4444-555555555555}
InProcServer32
(Default) = C:\MyDir\MyPropSheet.dll
ThreadingModel = Apartment
MyProgram.1
(Default) = MyProgram Application
Shellex
ContextMenuHandler
MyCommand
(Default) = {00000000-1111-2222-3333-444444444444}
PropertySheetHandlers
MyPropSheet
(Default) = {11111111-2222-3333-4444-555555555555}
El procedimiento de registro descrito en esta sección debe seguirse para todos los sistemas Windows.