创建 WMI 基类

为 WMI 提供程序创建新的 WMI 基类的建议方法是采用托管对象格式 (MOF) 文件。 还可以使用 COM API for WMI 创建基类。 虽然您可以在脚本中创建基类或派生类,但如果没有向类及其子类提供数据的提供程序,但该类就没有用处。

本主题包括以下部分:

使用 MOF 创建基类

WMI 类通常依赖于继承。 在创建基类之前,请检查分布式管理任务组 (DMTF) 中提供的通用信息模型 (CIM) 类。

如果许多派生类使用相同的属性,请将这些属性和方法放在基类中。 可以在 WMI 类中定义的最大属性数为 1024。

创建基类时,请遵循以下类名指南:

  • 同时使用大小写字母。

  • 类名以字母开头。

  • 不要使用前导或尾部下划线。

  • 将所有剩余字符定义为字母、数字或下划线。

  • 使用一致的命名约定。

    虽然不是必须的,但一个好的类名约定是用下划线联接的两个组件。 如果可能,供应商名称应构成名称的前半部分,描述性类名应是后半部分。

注意

执行提供程序期间无法更改类。 您必须停止活动,更改类,然后重启 Windows 管理服务。 目前无法检测类更改。

 

在 MOF 中,通过使用类关键字命名来创建基类,但不指明父类。

使用 MOF 代码创建基类

  1. 关键字与新类的名称一起使用,后跟一对大括号和分号。 在大括号之间添加类的属性和方法。 下方为代码示例。

    下面的代码示例演示如何定义基类。

    class MyClass_BaseDisk
    {
    };
    

    下面的代码示例显示了基类的错误定义。

    class MyClass_BaseDisk : CIM_LogicalDisk
    {
    };
    
  2. 在类关键字之前添加任何类限定符,从而修改类的使用方式。 将限定符放在方括号之间。 有关修改类的限定符的详细信息,请参阅 WMI 限定符。 使用抽象限定符指示不能直接创建此类的实例。 抽象类通常用于定义多个派生类将使用的属性或方法。 有关详细信息,请参阅创建派生类

    下面的代码示例将类定义为抽象类,并定义了提供数据的提供程序。 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. 通过在文件上运行 Mofcomp.exe,将类注册到 WMI。

    mofcomp.exe newmof.mof

    如果不使用 -N 开关或预处理器命令 #pragma 命名空间指定命名空间,则编译的 MOF 类将存储在存储库中的 root\default 命名空间中。 有关详细信息,请参阅 mofcomp

下面的代码示例结合了上一过程中讨论的 MOF 代码示例,并演示如何使用 MOF 在 root\cimv2 命名空间中创建基类。

#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++ 创建基类

使用 WMI API 创建基类主要是一系列 Put 命令,用于定义类并向 WMI 注册类。 此 API 的主要用途是使客户端应用程序能够创建基类。 但是,您还可以让提供程序使用此 API 创建基类。 例如,如果您认为提供程序的 MOF 代码不会正确安装,则可以指示提供程序在 WMI 存储库中自动创建正确的类。 有关提供程序的更多信息,请参见编写类提供程序

注意

执行提供程序期间无法更改类。 您必须停止活动,更改类,然后重启 Windows 管理服务。 目前无法检测类更改。

 

代码需要以下引用才能正确编译。

#include <wbemidl.h>

您可以使用适用于 COM API for WMI 以编程方式创建新的基类。

使用 WMI API 创建新的基类

  1. 通过调用 IWbemServices::GetObject 方法并将 strObjectPath 参数设置为值来检索新类的定义。

    下面的代码示例演示如何检索新类的定义。

    IWbemServices* pSvc = 0;
    IWbemContext* pCtx = 0;
    IWbemClassObject* pNewClass = 0;
    IWbemCallResult* pResult = 0;
    HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
    
  2. 通过使用对 IWbemClassObject::Put 方法的调用设置 __CLASS 系统属性来为类建立名称。

    下面的代码示例演示如何通过设置 __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. 首先调用 IWbemClassObject::GetPropertyQualifierSet 方法,然后调用 IWbemQualifierSet::Put 方法,将 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::Put 创建类的其他属性。

    下面的代码示例介绍如何创建其他属性。

      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();
    

下面的代码示例结合了上一过程中讨论的代码示例,演示如何使用 WMI API 创建基类。

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();
}

创建类