创建 WMI 派生类

在 WMI 中创建派生类与创建基类非常相似。 与基类一样,必须首先定义派生类,然后再向 WMI 注册派生类。 主要区别在于必须首先找到希望从中派生的父类。 有关详细信息,请参阅编写类提供程序编写实例提供程序

若要为提供程序创建类,建议使用托管对象格式 (MOF) 文件。 多个相互关联的派生类应与它们从中派生属性或方法的任何基类一起分组到一个 MOF 文件中。 如果将每个类放在单独的 MOF 文件中,则必须先编译每个文件,提供程序才能正常工作。

创建类后,必须先删除类的所有实例,然后才能对派生类执行下列任意活动:

  • 更改派生类的父类。
  • 添加或移除属性。
  • 更改属性类型。
  • 添加或移除 Key 或 Indexed 限定符。
  • 添加或移除 Singleton、Dynamic 或 Abstract 限定符。

注意

若要添加、移除或修改属性或限定符,请调用 IWbemServices::PutClassSWbemObject.Put_,并将 flag 参数设置为“强制模式”。 仅当父类为抽象类时,才能使用 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. 通过调用 IWbemClassObject::Put 方法设置 __CLASS 系统属性来建立类名称。

    以下代码示例演示如何为派生类分配名称。

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

结合上述过程中讨论的代码示例,以下代码示例介绍如何使用 WMI API 创建派生类。

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 文件

创建类