Создание производного класса WMI

Создание производного класса в WMI очень похоже на создание базового класса. Как и в случае с базовым классом, необходимо сначала определить производный класс, а затем зарегистрировать производный класс с помощью WMI. Отличие main заключается в том, что сначала необходимо найти родительский класс, от которого требуется наследовать. Дополнительные сведения см. в разделах Написание поставщика классов и Запись поставщика экземпляра.

Рекомендуемый способ создания классов для поставщика — в MOF-файлах. Несколько производных классов, связанных друг с другом, следует сгруппировать в MOF-файл, а также все базовые классы, от которых они являются производными свойствами или методами. Если вы размещаете каждый класс в отдельный MOF-файл, каждый файл должен быть скомпилирован, прежде чем поставщик сможет правильно работать.

После создания класса необходимо удалить все его экземпляры, прежде чем можно будет выполнить любое из следующих действий в производном классе:

  • Измените родительский класс производного класса.
  • Добавление или удаление свойств.
  • Изменение типов свойств.
  • Добавление или удаление квалификаторов key или indexed .
  • Добавление или удаление одноэлементных, динамических или абстрактных квалификаторов.

Примечание

Чтобы добавить, удалить или изменить свойство или квалификатор, вызовите IWbemServices::P utClass или SWbemObject.Put_ и задайте для параметра флага значение force mode. Квалификатор Abstract можно использовать только в том случае, если родительский класс является абстрактным.

 

При объявлении производного класса соблюдайте следующие правила и ограничения:

  • Родительский класс производного класса уже должен существовать.

    Объявление родительского класса может отображаться в том же MOF-файле, что и производный класс, или в другом файле. Если родительский класс неизвестен, компилятор создает ошибку во время выполнения.

  • Производный класс может иметь только один родительский класс.

    WMI не поддерживает множественное наследование. Однако родительский класс может иметь множество производных классов.

  • Можно определить индексы для производных классов, но WMI не использует эти индексы.

    Поэтому указание индекса в производном классе не повышает производительность запросов для экземпляров производного класса. Вы можете повысить производительность запроса в производном классе, указав индексированные свойства для родительского класса производного класса.

  • Определения производных классов могут быть более сложными и включать такие функции, как псевдонимы, квалификаторы и варианты квалификаторов.

    Дополнительные сведения см. в разделах Создание псевдонима и Добавление квалификатора.

  • Если вы хотите изменить квалификатор, изменить значение по умолчанию свойства базового класса или более строго ввести свойство ссылочного или внедренного объекта базового класса, необходимо снова объявить весь базовый класс.

  • Максимальное количество свойств, которые можно определить в классе WMI, равно 1024.

Примечание

Классы нельзя изменить во время выполнения поставщиков. Необходимо остановить действие, изменить класс, а затем перезапустить службу управления Windows. Обнаружение изменения класса в настоящее время невозможно.

 

Как и в случае с базовым классом, чаще всего этот метод используется клиентскими приложениями. Однако поставщик также может создать производный класс. Дополнительные сведения см. в разделах Создание базового класса и Написание поставщика классов.

Для правильной компиляции в примере кода в этом разделе требуется следующая инструкция #include.

#include <wbemidl.h>

В следующей процедуре описывается создание производного класса с помощью C++.

Создание производного класса с помощью C++

  1. Найдите базовый класс с помощью вызова IWbemServices::GetObject.

    В следующем примере кода показано, как найти базовый класс Example.

    // 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. Создайте производный объект из базового класса с помощью вызова IWbemClassObject::SpawnDerivedClass.

    В следующем примере кода показано, как создать объект производного класса.

    pExampleClass->SpawnDerivedClass(0, &pNewDerivedClass);
    pExampleClass->Release();  // Don't need the parent class any more
    
  3. Задайте имя для класса , задав системное свойство __CLASS с помощью вызова метода IWbemClassObject::P ut .

    В следующем примере кода показано, как назначить имя производного класса.

    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. Создайте дополнительные свойства с помощью IWbemClassObject::P ut.

    В следующем примере кода показано, как создать дополнительные свойства.

    BSTR OtherProp = SysAllocString(L"OtherInfo2");
    pNewDerivedClass->Put(OtherProp, 0, NULL, CIM_STRING); 
    SysFreeString(OtherProp);
    
  5. Сохраните новый класс, вызвав IWbemServices::P utClass.

    В следующем примере кода показано, как сохранить новый производный класс.

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

В следующем примере кода объединяются примеры кода, рассмотренные в предыдущей процедуре, чтобы описать создание производного класса с помощью API 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();
}

В следующей процедуре описывается определение производного класса с помощью MOF-кода.

Определение производного класса с помощью MOF-кода

  1. Определите производный класс с помощью ключевое слово Class, за которым следует имя производного класса и имя родительского класса, разделенное двоеточием.

    В следующем примере кода описывается реализация производного класса.

    class MyClass 
    {
        [key] string   strProp;
        sint32   dwProp1;
        uint32       dwProp2;
    };
    
    class MyDerivedClass : MyClass
    {
        string   strDerivedProp;
        sint32   dwDerivedProp;
    };
    
  2. После завершения скомпилируйте MOF-код с помощью компилятора MOF.

    Дополнительные сведения см. в разделе Компиляция MOF-файлов.

Создание класса