使用 C++ 创建和声明实例

可以通过 IWbemServices 接口在 C++ 中创建实例。

本主题中的代码示例需要以下 #include 语句才能正确编译。

#include <wbemidl.h>

以下过程介绍如何创建现有类的实例。

创建现有类的实例

  1. 通过调用 IWbemServices::GetObjectIWbemServices::GetObjectAsync 方法检索现有类的定义。

    下面的代码示例演示如何使用 GetObjectGetObjectAsync 方法获取指向 IWbemClassObject 接口的指针,该接口提供对类定义的访问权限。

    // The pSv variable is of type IWbemServices *
    
    IWbemClassObject *pNewInstance = 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::SpawnInstance 方法创建新实例。

    以下代码示例演示如何创建新实例,然后释放类。

    pExampleClass->SpawnInstance(0, &pNewInstance);
    pExampleClass->Release();  // Don't need the class any more
    
  3. 通过调用 IWbemClassObject::Put 方法,为不继承为类定义的值的任何属性设置值。

    类的每个实例都继承为类定义的所有属性。 但是,如果愿意,可以指定不同的属性值。

    如果现有类具有键属性,则应将属性设置为 NULL 或保证的唯一值。 如果将密钥设置为 NULL,并且密钥是字符串,则 PutInstanceAsyncPutInstance 会在内部生成 GUID 并将其分配给密钥。 那么,为键属性指定 NULL 即可创建不会覆盖任何先前实例的唯一实例。

    以下代码示例演示如何设置示例实例类的索引属性值。

    VARIANT v;
    VariantInit(&v);
    
    V_VT(&v) = VT_BSTR;
    V_BSTR(&v) = SysAllocString(L"IX100");
    
    BSTR KeyProp = SysAllocString(L"Index");
    pNewInstance->Put(KeyProp, 0, &v, 0);
    SysFreeString(KeyProp);
    VariantClear(&v);
    
  4. 通过调用 IWbemClassObject::GetQualifierSet 来设置任何相关限定符的值。

    GetQualifierSet 方法返回指向 IWbemQualifierSet 接口的指针,该接口用于访问类或实例的限定符。 如果类限定符特色信息为 EnableOverride,则可以为为类定义的限定符指定不同的值。 不能修改或删除特色信息设置为 DisableOverride 的类限定符。 有关详细信息,请参阅限定符特色信息

    作为一个选项,还可以为实例类定义其他限定符。 可以为不需要出现在类声明中的实例或实例属性定义其他限定符。

  5. 通过调用 IWbemServices::P utInstanceIWbemServices::P utInstanceAsync 方法保存实例。

    WMI 将实例保存在当前 WMI 命名空间中。 因此,实例的完整路径依赖于命名空间,通常为 root\default。 对于此代码示例,完整路径名称为 \\.\root\default:Example.Index="IX100"。

    以下代码示例演示如何创建对象。

        hRes = pSvc->PutInstance(pNewInstance, 0, pCtx, &pResult);
        pNewInstance->Release();
    

将实例保存到 WMI 会锁定实例的多个属性。

具体而言,在 WMI 基础结构中存在实例后,无法通过 WMI API 执行以下操作:

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

以下代码示例结合了前面过程中讨论的代码示例,以演示如何使用 WMI API 创建实例。

void CreateInstance (IWbemServices *pSvc)
{
    IWbemClassObject *pNewInstance = 0;
    IWbemClassObject *pExampleClass = 0;
    IWbemContext *pCtx = 0;
    IWbemCallResult *pResult = 0;

    // Get the class definition.
    BSTR PathToClass = SysAllocString(L"Example");
    HRESULT hRes = pSvc->GetObject(PathToClass, 0, pCtx, 
                 &pExampleClass, &pResult);
    SysFreeString(PathToClass);

    if (hRes != 0)
       return;

    // Create a new instance.
    pExampleClass->SpawnInstance(0, &pNewInstance);
    pExampleClass->Release();  // Don't need the class any more

    VARIANT v;
    VariantInit(&v);

    // Set the Index property (the key).
    V_VT(&v) = VT_BSTR;
    V_BSTR(&v) = SysAllocString(L"IX100");

    BSTR KeyProp = SysAllocString(L"Index");
    pNewInstance->Put(KeyProp, 0, &v, 0);
    SysFreeString(KeyProp);
    VariantClear(&v);

    // Set the IntVal property.
    V_VT(&v) = VT_I4;
    V_I4(&v) = 1001;  
    
    BSTR Prop = SysAllocString(L"IntVal");
    pNewInstance->Put(Prop, 0, &v, 0);
    SysFreeString(Prop);
    VariantClear(&v);    
    
    // Other properties acquire the 'default' value specified
    // in the class definition unless otherwise modified here.

    // Write the instance to WMI. 
    hRes = pSvc->PutInstance(pNewInstance, 0, pCtx, &pResult);
    pNewInstance->Release();
}