Crear una clase base WMI

La manera recomendada de crear una nueva clase base WMI para un proveedor WMI es en un archivo Managed Object Format (MOF). También puede crear una clase base mediante la API COM para WMI. Aunque puede crear una clase base o derivada en el script, sin que un proveedor proporcione datos a la clase y sus subclases, la clase no es útil.

En este tema se describen las secciones siguientes:

Crear una clase base mediante MOF

Las clases WMI se suelen basar en la herencia. Antes de crear una clase base, compruebe las clases de Modelo de información común (CIM) disponibles en el Grupo de tareas de administración distribuida (DMTF).

Si muchas clases derivadas usarán las mismas propiedades, coloque estas propiedades y métodos en la clase base. El número máximo de propiedades que puede definir en una clase WMI es 1024.

Al crear una clase base, observe la siguiente lista de instrucciones para los nombres de clase:

  • Use letras tanto mayúsculas como minúsculas.

  • Comience el nombre de una clase con una letra.

  • No use un carácter de guion bajo al inicio o al final.

  • Defina todos los caracteres restantes como letras, dígitos o caracteres de guion bajo.

  • Usar una convención de nomenclatura consistente.

    Aunque no es necesario, una buena convención de nomenclatura para una clase es dos componentes unidos por un carácter de guion bajo. Cuando sea posible, la primera mitad del nombre debe estar formado por el nombre del vendedor y, la segunda, por un nombre de clase descriptivo.

Nota

Las clases no se pueden cambiar durante la ejecución de los proveedores. Debe detener la actividad, cambiar la clase y, a continuación, reiniciar el servicio de administración de Windows. Actualmente no es posible detectar un cambio de clase.

 

En MOF, cree una clase base con la palabra clave class, pero no indique una clase primaria.

Para crear una clase base mediante código MOF

  1. Use la palabra clave class con el nombre de la nueva clase, seguida de un par de llaves y un punto y coma. Agregue propiedades y métodos para la clase entre las llaves. Se proporciona el ejemplo de código siguiente.

    En el ejemplo de código siguiente se muestra cómo se debe definir una clase base.

    class MyClass_BaseDisk
    {
    };
    

    En el ejemplo de código siguiente se muestra una definición incorrecta de una clase base.

    class MyClass_BaseDisk : CIM_LogicalDisk
    {
    };
    
  2. Agregue los calificadores de cualquier clase antes de la palabra clave class para modificar la forma en que se usa la clase. Coloque los calificadores entre corchetes. Para obtener más información sobre los calificadores para modificar clases, consulte Calificadores WMI. Use el calificador Abstract para indicar que no se puede crear una instancia de esta clase directamente. Las clases abstractas se suelen usar para definir propiedades o métodos que usarán varias clases derivadas. Para obtener más información, consulte Crear una clase derivada.

    En el ejemplo de código siguiente se define la clase como abstracta y se define el proveedor que proporcionará los datos. El tipo de calificador ToSubClass indica que la información del calificador Provider se hereda por clases derivadas.

    [Abstract, Provider("MyProvider") : ToSubClass]
    class MyClass_BaseDisk
    {
    };
    
  3. Agregue las propiedades y los métodos de la clase entre corchetes antes de la propiedad o el nombre del método. Para obtener más información, consulte Agregar una propiedad y Crear un método. Puede modificar estas propiedades y métodos mediante calificadores MOF. Para obtener más información, consulte Añadir un calificador.

    En el ejemplo de código siguiente se muestra cómo modificar propiedades y métodos con calificadores MOF.

    [read : ToSubClass, key : ToSubClass ] string DeviceID;
      [read : ToSubClass] uint32 State;
      [read : ToSubclass, write : ToSubClass] uint64 LimitUsers;
    
  4. Guarde el archivo MOF con una extensión .mof.

  5. Registre la clase con WMI ejecutando Mofcomp.exe en el archivo.

    mofcomp.exenewmof.mof

    Si no usa el modificador -N o el comando de preprocesador #pragma namespace para especificar un espacio de nombres, las clases MOF compiladas se almacenarán en el espacio de nombres root\default del repositorio. Para obtener más información, consulte mofcomp.

En el ejemplo de código siguiente se combinan los ejemplos de código MOF descritos en el procedimiento anterior y se muestra cómo crear una clase base en el espacio de nombres root\cimv2 mediante MOF.

#pragma namespace("\\\\.\\Root\\cimv2")

[Abstract, Provider("MyProvider") : ToSubClass]
class MyClass_BaseDisk
{
  [read : ToSubClass, key : ToSubClass ] string DeviceID;
  [read : ToSubClass] uint32 State;
  [read : ToSubClass, write : ToSubClass] uint64 LimitUsers;
};

Para obtener más información, consulte Crear una clase derivada para obtener un ejemplo de una clase dinámica derivada de esta clase base.

Crear una clase base con C++

La creación de una clase base mediante la API de WMI es principalmente una serie de comandos Put que definen la clase y registran la clase con WMI. El propósito principal de esta API es permitir que las aplicaciones cliente creen clases base. Sin embargo, también puede tener un proveedor que use esta API para crear una clase base. Por ejemplo, si cree que el código MOF para el proveedor no se instalará correctamente, puede indicar al proveedor que cree automáticamente las clases correctas en el repositorio WMI. Para obtener más información sobre los proveedores, consulte Escribir un proveedor de clases.

Nota

Las clases no se pueden cambiar durante la ejecución de los proveedores. Debe detener la actividad, cambiar la clase y, a continuación, reiniciar el servicio de administración de Windows. Actualmente no es posible detectar un cambio de clase.

 

El código requiere la siguiente referencia para compilarse correctamente.

#include <wbemidl.h>

Puede crear una nueva clase base mediante programando mediante la API COM para WMI.

Para crear una nueva clase base con la API de WMI

  1. Recupere una definición para la nueva clase llamando al método IWbemServices::GetObject con el parámetro strObjectPath establecido en un valor null.

    En el ejemplo de código siguiente se muestra cómo recuperar una definición para una nueva clase.

    IWbemServices* pSvc = 0;
    IWbemContext* pCtx = 0;
    IWbemClassObject* pNewClass = 0;
    IWbemCallResult* pResult = 0;
    HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
    
  2. Establezca un nombre para la clase estableciendo la propiedad del sistema __CLASS con una llamada al método IWbemClassObject::P ut.

    En el ejemplo de código siguiente se muestra cómo asignar un nombre a la clase estableciendo la propiedad del sistema __CLASS.

    VARIANT v;
    VariantInit(&v);
    V_VT(&v) = VT_BSTR;
    
    V_BSTR(&v) = SysAllocString(L"Example");
    BSTR Class = SysAllocString(L"__CLASS");
    pNewClass->Put(Class, 0, &v, 0);
    SysFreeString(Class);
    VariantClear(&v);
    
  3. Cree la propiedad o las propiedades de clave llamando a IWbemClassObject::Put.

    En el ejemplo de código siguiente se describe cómo crear la propiedad Index, que se etiqueta como una propiedad de clave en el paso 4.

      BSTR KeyProp = SysAllocString(L"Index");
      pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);
    
  4. Adjunte el calificador estándar de key a la propiedad key llamando primero al método IWbemClassObject::GetPropertyQualifierSet y, a continuación, al método IWbemQualifierSet::Put.

    En el ejemplo de código siguiente se muestra cómo adjuntar el calificador estándar key a la propiedad key.

      IWbemQualifierSet *pQual = 0;
      pNewClass->GetPropertyQualifierSet(KeyProp, &pQual);
      SysFreeString(KeyProp);
    
      V_VT(&v) = VT_BOOL;
      V_BOOL(&v) = VARIANT_TRUE;
      BSTR Key = SysAllocString(L"Key");
    
      pQual->Put(Key, &v, 0);   // Flavors not required for Key 
      SysFreeString(Key);
    
      // No longer need the qualifier set for "Index"
      pQual->Release();   
      VariantClear(&v);
    
  5. Cree otras propiedades de la clase con IWbemClassObject::Put.

    En el siguiente ejemplo de código se muestra cómo crear propiedades adicionales.

      V_VT(&v) = VT_BSTR;
      V_BSTR(&v) = SysAllocString(L"<default>");
      BSTR OtherProp = SysAllocString(L"OtherInfo");
      pNewClass->Put(OtherProp, 0, &v, CIM_STRING);
      SysFreeString(OtherProp);
      VariantClear(&v);
    
      OtherProp = SysAllocString(L"IntVal");
      pNewClass->Put(OtherProp, 0, NULL, CIM_SINT32); // NULL is default
      SysFreeString(OtherProp);
    
  6. Registre la nueva clase llamando a IWbemServices::PutClass.

    Dado que no puede definir claves e índices después de registrar una nueva clase, asegúrese de que ha definido todas las propiedades antes de llamar a PutClass.

    En el siguiente ejemplo de código se muestra cómo registrar una nueva clase.

      hRes = pSvc->PutClass(pNewClass, 0, pCtx, &pResult);
      pNewClass->Release();
    

En el ejemplo de código siguiente se combinan los ejemplos de código descritos en el procedimiento anterior y se muestra cómo crear una clase base mediante la API de WMI.

void CreateClass(IWbemServices *pSvc)
{
  IWbemClassObject *pNewClass = 0;
  IWbemContext *pCtx = 0;
  IWbemCallResult *pResult = 0;

  // Get a class definition. 
  // ============================
  HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
  VARIANT v;
  VariantInit(&v);

  // Create the class name.
  // ============================
  V_VT(&v) = VT_BSTR;
  V_BSTR(&v) = SysAllocString(L"Example");
  BSTR Class = SysAllocString(L"__CLASS");
  pNewClass->Put(Class, 0, &v, 0);
  SysFreeString(Class);
  VariantClear(&v);

  // Create the key property. 
  // ============================
  BSTR KeyProp = SysAllocString(L"Index");
  pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);

  // Attach Key qualifier to mark the "Index" property as the key.
  // ============================
  IWbemQualifierSet *pQual = 0;
  pNewClass->GetPropertyQualifierSet(KeyProp, &pQual);
  SysFreeString(KeyProp);

  V_VT(&v) = VT_BOOL;
  V_BOOL(&v) = VARIANT_TRUE;
  BSTR Key = SysAllocString(L"Key");

  pQual->Put(Key, &v, 0);   // Flavors not required for Key 
  SysFreeString(Key);

  // No longer need the qualifier set for "Index"
  pQual->Release();     
  VariantClear(&v);

  // Create other properties.
  // ============================
  V_VT(&v) = VT_BSTR;
  V_BSTR(&v) = SysAllocString(L"<default>");
  BSTR OtherProp = SysAllocString(L"OtherInfo");
  pNewClass->Put(OtherProp, 0, &v, CIM_STRING);
  SysFreeString(OtherProp);
  VariantClear(&v);

  OtherProp = SysAllocString(L"IntVal");
  pNewClass->Put(OtherProp, 0, NULL, CIM_SINT32); // NULL is default
  SysFreeString(OtherProp);
  
  // Register the class with WMI
  // ============================
  hRes = pSvc->PutClass(pNewClass, 0, pCtx, &pResult);
  pNewClass->Release();
}

Crear una clase