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

Рекомендуемый способ создания нового базового класса WMI для поставщика WMI — в MOF-файле. Вы также можете создать базовый класс с помощью COM API для WMI. Хотя вы можете создать базовый или производный класс в скрипте, без поставщика, предоставляющего данные для класса и его подклассов, класс не является полезным.

В этой статье рассматриваются следующие разделы:

Создание базового класса с помощью MOF

Классы WMI обычно зависят от наследования. Перед созданием базового класса проверка классы CIM, доступные в распределенной целевой группе управления (DMTF).

Если многие производные классы будут использовать одни и те же свойства, поместите эти свойства и методы в базовый класс. Максимальное количество свойств, которые можно определить в классе WMI, — 1024.

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

  • Используйте прописные и строчные буквы.

  • Имя класса начинается с буквы.

  • Не используйте начальный или конечный символ подчеркивания.

  • Определите все оставшиеся символы в виде букв, цифр или символов подчеркивания.

  • Используйте согласованное соглашение об именовании.

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

Примечание

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

 

В MOF создайте базовый класс, назвав его классом ключевое слово, но не указывая родительский класс.

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

  1. Используйте класс ключевое слово с именем нового класса, за которым следует пара фигурных скобок и точка с запятой. Добавьте свойства и методы для класса между фигурными скобками. Ниже приведен пример кода.

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

    class MyClass_BaseDisk
    {
    };
    

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

    class MyClass_BaseDisk : CIM_LogicalDisk
    {
    };
    
  2. Добавьте квалификаторы класса перед ключевое слово класса, чтобы изменить способ использования класса. Поместите квалификаторы между квадратными скобками. Дополнительные сведения о квалификаторах для изменения классов см. в разделе Квалификаторы WMI. Используйте квалификатор Abstract , чтобы указать, что невозможно создать экземпляр этого класса напрямую. Абстрактные классы часто используются для определения свойств или методов, которые будут использоваться несколькими производными классами. Дополнительные сведения см. в разделе Создание производного класса.

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

    [Abstract, Provider("MyProvider") : ToSubClass]
    class MyClass_BaseDisk
    {
    };
    
  3. Добавьте свойства и методы для класса в квадратные скобки перед именем свойства или метода. Дополнительные сведения см. в разделах Добавление свойства и Создание метода. Эти свойства и методы можно изменить с помощью квалификаторов MOF. Дополнительные сведения см. в разделе Добавление квалификатора.

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

    [read : ToSubClass, key : ToSubClass ] string DeviceID;
      [read : ToSubClass] uint32 State;
      [read : ToSubclass, write : ToSubClass] uint64 LimitUsers;
    
  4. Сохраните MOF-файл с расширением MOF.

  5. Зарегистрируйте класс с помощью WMI, запустив Mofcomp.exe в файле .

    mofcomp.exenewmof.mof

    Если вы не используете параметр -N или команду препроцессора #pragma namespace для указания пространства имен, скомпилированные классы MOF будут храниться в корневом пространстве имен по умолчанию в репозитории. Дополнительные сведения см. в разделе mofcomp.

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

Дополнительные сведения см. в разделе Создание производного класса для примера динамического класса, производного от этого базового класса.

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

Создание базового класса с помощью API WMI в основном представляет собой серию команд Put, которые определяют класс и регистрируют класс с помощью WMI. Main цель этого API — разрешить клиентским приложениям создавать базовые классы. Однако поставщик также может использовать этот API для создания базового класса. Например, если вы считаете, что MOF-код для поставщика не будет установлен должным образом, можно указать поставщику автоматически создать правильные классы в репозитории WMI. Дополнительные сведения о поставщиках см. в разделе Написание поставщика классов.

Примечание

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

 

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

#include <wbemidl.h>

Вы можете создать новый базовый класс программным способом с помощью COM API для WMI.

Создание базового класса с помощью API WMI

  1. Получите определение для нового класса, вызвав метод IWbemServices::GetObject с параметром strObjectPath , для которого задано значение NULL .

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

    IWbemServices* pSvc = 0;
    IWbemContext* pCtx = 0;
    IWbemClassObject* pNewClass = 0;
    IWbemCallResult* pResult = 0;
    HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
    
  2. Задайте имя для класса, задав системное свойство __CLASS с помощью вызова метода IWbemClassObject::P ut .

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

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

      BSTR KeyProp = SysAllocString(L"Index");
      pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);
    
  4. Присоедините стандартный квалификатор Key к свойству key, сначала вызвав метод IWbemClassObject::GetPropertyQualifierSet , а затем метод IWbemQualifierSet::P ut .

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

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

      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. Зарегистрируйте новый класс, вызвав IWbemServices::P utClass.

    Так как вы не можете определить ключи и индексы после регистрации нового класса, убедитесь, что вы определили все свойства перед вызовом PutClass.

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

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

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

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