Crear una clase derivada de WMI

Crear una clase derivada en WMI es muy similar a crear una clase base. Al igual que con una clase base, primero debe definir la clase derivada y, posteriormente, registrar la clase derivada con WMI. La principal diferencia es que primero debe buscar la clase principal desde la que quiere derivar. Para obtener más información, consulte Escritura de un proveedor de clases y Escritura de un proveedor de instancias.

La manera recomendada de crear clases para un proveedor es en archivos Managed Object Format (MOF). Varias clases derivadas relacionadas entre sí deben agruparse en un archivo MOF, junto con las clases base de las que se derivan las propiedades o métodos. Si coloca cada clase en un archivo MOF independiente, cada archivo debe compilarse para que el proveedor pueda trabajar correctamente.

Después de crear la clase, debe eliminar todas las instancias de la clase para poder realizar cualquiera de las actividades siguientes en la clase derivada:

  • Cambie la clase principal de la clase derivada.
  • Agregue o quite propiedades.
  • Cambie los tipos de propiedad.
  • Agregue o quite los calificadores Key o Indexed.
  • Agregue o quite los calificadores Singleton, Dynamic o Abstract.

Nota:

Para agregar, quitar o modificar una propiedad o un calificador, llame a IWbemServices::PutClass o SWbemObject.Put_ y establezca el parámetro flag en "force mode". El calificador Abstract solo se puede usar si la clase principal es abstracta.

 

Al declarar la clase derivada, siga las siguientes reglas y restricciones:

  • La clase principal de la clase derivada ya debe existir.

    La declaración de la clase principal puede aparecer en el mismo archivo MOF que la clase derivada o en un archivo diferente. Si se desconoce la clase principal, el compilador genera un error en tiempo de ejecución.

  • Una clase derivada solo puede tener una sola clase principal.

    WMI no admite la herencia múltiple. Sin embargo, una clase principal puede tener muchas clases derivadas.

  • Puede definir índices para las clases derivadas, pero WMI no usa estos índices.

    Por lo tanto, especificar un índice en una clase derivada no mejora el rendimiento de las consultas para instancias de la clase derivada. Puede mejorar el rendimiento de una consulta en una clase derivada especificando propiedades indizadas para la clase principal de la clase derivada.

  • Las definiciones de clase derivadas pueden ser más complejas y pueden incluir características como alias, calificadores y tipos de calificador.

    Para obtener más información, consulte Crear un alias y Agregar un calificador.

  • Si quiere cambiar un calificador, cambiar el valor predeterminado de una propiedad de clase base o crear de forma más fuertemente tipada una propiedad de objeto incrustada o de referencia de una clase base, debe declarar de nuevo toda la clase base.

  • El número máximo de propiedades que puede definir en una clase WMI es 1024.

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.

 

Al igual que sucede con la clase base, el uso más común de esta técnica serán las aplicaciones cliente. Sin embargo, un proveedor también puede crear una clase derivada. Para obtener más información, consulte Crear una clase base y escribir un proveedor de clases.

El ejemplo de código de este tema requiere la siguiente instrucción #include para compilarse correctamente.

#include <wbemidl.h>

En el procedimiento siguiente se describe cómo crear una clase derivada mediante C++.

Para crear una clase derivada mediante C++

  1. Localice la clase base con una llamada a IWbemServices::GetObject.

    En el ejemplo de código siguiente se muestra cómo se localiza la clase base de ejemplo.

    // The pSv variable is of type IWbemServices *
    
    IWbemClassObject *pNewDerivedClass = 0;
    IWbemClassObject *pExampleClass = 0;
    IWbemContext *pCtx = 0;
    IWbemCallResult *pResult = 0;
    
    BSTR PathToClass = SysAllocString(L"Example");
    HRESULT hRes = pSvc->GetObject(PathToClass, 0, pCtx, &pExampleClass, &pResult);
    SysFreeString(PathToClass);
    
  2. Cree un objeto derivado de la clase base con una llamada a IWbemClassObject::SpawnDerivedClass.

    En el ejemplo de código siguiente se muestra cómo crear un objeto de clase derivada.

    pExampleClass->SpawnDerivedClass(0, &pNewDerivedClass);
    pExampleClass->Release();  // Don't need the parent class any more
    
  3. 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 derivada.

    VARIANT v;
    VariantInit(&v);
    
    V_VT(&v) = VT_BSTR;
    V_BSTR(&v) = SysAllocString(L"Example2");
    BSTR Class = SysAllocString(L"__CLASS");
    pNewDerivedClass->Put(Class, 0, &v, 0);
    SysFreeString(Class);
    VariantClear(&v);
    
  4. Cree propiedades adicionales con IWbemClassObject::Put.

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

    BSTR OtherProp = SysAllocString(L"OtherInfo2");
    pNewDerivedClass->Put(OtherProp, 0, NULL, CIM_STRING); 
    SysFreeString(OtherProp);
    
  5. Guarde la nueva clase llamando a IWbemServices::PutClass.

    En el ejemplo de código siguiente se muestra cómo guardar la nueva clase derivada.

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

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

void CreateDerivedClass(IWbemServices *pSvc)
{
  IWbemClassObject *pNewDerivedClass = 0;
  IWbemClassObject *pExampleClass = 0;
  IWbemContext *pCtx = 0;
  IWbemCallResult *pResult = 0;

  BSTR PathToClass = SysAllocString(L"Example");
  HRESULT hRes = pSvc->GetObject(PathToClass, 0, pCtx, 
    &pExampleClass, &pResult);
  SysFreeString(PathToClass);

  if (hRes != 0)
    return;

  pExampleClass->SpawnDerivedClass(0, &pNewDerivedClass);
  pExampleClass->Release();  // The parent class is no longer needed

  VARIANT v;
  VariantInit(&v);

  // Create the class name.
  // =====================

  V_VT(&v) = VT_BSTR;
  V_BSTR(&v) = SysAllocString(L"Example2");
  BSTR Class = SysAllocString(L"__CLASS");
  pNewDerivedClass->Put(Class, 0, &v, 0);
  SysFreeString(Class);
  VariantClear(&v);

  // Create another property.
  // =======================
  BSTR OtherProp = SysAllocString(L"OtherInfo2");
  // No default value
  pNewDerivedClass->Put(OtherProp, 0, NULL, CIM_STRING); 
  SysFreeString(OtherProp);
  
  // Register the class with WMI. 
  // ============================
  hRes = pSvc->PutClass(pNewDerivedClass, 0, pCtx, &pResult);
  pNewDerivedClass->Release();
}

En el procedimiento siguiente se describe cómo definir una clase derivada mediante código MOF.

Para definir una clase derivada mediante código MOF

  1. Defina la clase derivada con la palabra clave Class, seguida del nombre de la clase derivada y el nombre de la clase principal separados por dos puntos.

    En el ejemplo de código siguiente se describe una implementación de una clase derivada.

    class MyClass 
    {
        [key] string   strProp;
        sint32   dwProp1;
        uint32       dwProp2;
    };
    
    class MyDerivedClass : MyClass
    {
        string   strDerivedProp;
        sint32   dwDerivedProp;
    };
    
  2. Cuando haya finalizado, compile el código MOF con el compilador MOF.

    Para obtener más información, consulte Compilar archivos MOF.

Crear una clase