Поделиться через


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

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

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

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

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

Заметка

Чтобы добавить, удалить или изменить свойство или квалификатор, вызовите IWbemServices::PutClass или 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::Put.

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

    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::Put.

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

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

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

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

    Подробнее см. в разделе Компиляция файлов MOF.

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