Creating and Declaring an Instance Using C++

You can create an instance in C++ through the IWbemServices interface.

The code examples in this topic require the following #include statement to compile correctly.

#include <wbemidl.h>

The following procedure describes how to create an instance of an existing class.

To create an instance of an existing class

  1. Retrieve the definition of the existing class by calling the IWbemServices::GetObject or IWbemServices::GetObjectAsync methods.

    The following code example shows how to use the GetObject and GetObjectAsync methods to get a pointer to the IWbemClassObject interface that provides access to the class definition.

    // 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. Create the new instance by calling the IWbemClassObject::SpawnInstance method.

    The following code example shows how to create a new instance and then release the class.

    pExampleClass->SpawnInstance(0, &pNewInstance);
    pExampleClass->Release();  // Don't need the class any more
    
  3. Set values for any properties that do not inherit the values defined for the class by calling the IWbemClassObject::Put method.

    Each instance of a class inherits all of the properties that are defined for the class. However, you can specify different property values if you choose.

    If the existing class has a key property, you should set the property either to NULL or a guaranteed unique value. If you set the key to NULL and the key is a string, then PutInstanceAsync or PutInstance internally generates and assigns a GUID to the key. This way, specifying NULL for a key property lets you create a unique instance that will not overwrite any previous instance.

    The following code example shows how to set the Index property value of the example instance class.

    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. Set the values for any relevant qualifiers through a call to IWbemClassObject::GetQualifierSet.

    The GetQualifierSet method returns a pointer to an IWbemQualifierSet interface, which use to access the qualifiers for a class or instance. You can specify different values for a qualifier defined for the class if the class qualifier flavor is EnableOverride. You cannot modify or delete a class qualifier with the flavor set to DisableOverride. For more information, see Qualifier Flavors.

    As an option, you can also define additional qualifiers for your instance class. You can define additional qualifiers for the instance or instance property which do not need to appear in the class declaration.

  5. Save the instance by calling the IWbemServices::PutInstance or IWbemServices::PutInstanceAsync method.

    WMI saves the instance in the current WMI namespace. As such, the full path of the instance is dependent on the namespace, which is typically root\default. For this code example, the full path name would be \\.\root\default:Example.Index="IX100".

    The following code example shows how to save an instance.

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

Saving the instance to WMI locks down several of the properties of the instance.

Specifically, you cannot perform any of the following operations through the WMI API after an instance exists within the WMI infrastructure:

  • Change the parent class of the class to which the instance belongs.
  • Add or remove properties.
  • Change property types.
  • Add or remove Key or Indexed qualifiers.
  • Add or remove Singleton, Dynamic, or Abstract qualifiers.

The following code example combines the code examples discussed in the previous procedure to show how to create an instance using the 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();
}