Criar e declarar uma instância usando C++

Você pode criar uma instância em C++ por meio da interface IWbemServices.

Os exemplos de código neste tópico exigem que as instrução #include a seguir seja compiladas corretamente.

#include <wbemidl.h>

O procedimento a seguir descreve como criar uma instância de uma classe existente.

Para criar uma instância de uma classe existente

  1. Recupere a definição da classe existente chamando os métodos IWbemServices::GetObject ou IWbemServices::GetObjectAsync.

    O exemplo de código a seguir mostra como usar os métodos GetObject e GetObjectAsync para obter um ponteiro para a interface IWbemClassObject que fornece acesso à definição de classe.

    // 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. Crie a nova instância chamando o método IWbemClassObject::SpawnInstance.

    O exemplo de código a seguir mostra como criar uma nova instância e, em seguida, liberar a classe.

    pExampleClass->SpawnInstance(0, &pNewInstance);
    pExampleClass->Release();  // Don't need the class any more
    
  3. Defina valores para quaisquer propriedades que não herdem os valores definidos para a classe chamando o método IWbemClassObject::P ut.

    Cada instância de uma classe herda todas as propriedades definidas para a classe. No entanto, você pode especificar valores de propriedade diferentes se desejar.

    Se a classe existente tiver uma propriedade de chave, você deverá definir a propriedade como NULL ou um valor exclusivo garantido. Se você definir a chave como NULL e a chave for uma cadeia de caracteres, PutInstanceAsync ou PutInstance gerará e atribuirá internamente um GUID à chave. Dessa forma, especificar NULL para uma propriedade de chave permite criar uma instância exclusiva que não substituirá nenhuma instância anterior.

    O exemplo de código a seguir mostra como definir o valor da propriedade Index da classe de instância de exemplo.

    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. Defina os valores para quaisquer qualificadores relevantes por meio de uma chamada para IWbemClassObject::GetQualifierSet.

    O método GetQualifierSet retorna um ponteiro para uma interface IWbemQualifierSet, que usa para acessar os qualificadores de uma classe ou instância. Você poderá especificar valores diferentes para um qualificador definido para a classe se o tipo de qualificador de classe for EnableOverride. Não é possível modificar ou excluir um qualificador de classe com o tipo definido como DisableOverride. Para obter mais informações, consulte Variantes qualificadoras.

    Como opção, você também pode definir qualificadores adicionais para sua classe de instância. Você pode definir qualificadores adicionais para a instância ou propriedade de instância que não precisam aparecer na declaração de classe.

  5. Salve a instância chamando o método IWbemServices::PutInstance ou IWbemServices::PutInstanceAsync.

    O WMI salva a instância no namespace do WMI atual. Dessa forma, o caminho completo da instância depende do namespace, que normalmente é root\default. Para este exemplo de código, o nome do caminho completo seria \\.\root\default:Example.Index="IX100".

    O exemplo de código a seguir mostra como salvar uma instância.

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

Salvar a instância no WMI bloqueia várias das propriedades da instância.

Especificamente, você não pode executar nenhuma das seguintes operações por meio da API do WMI depois que uma instância existe na infraestrutura WMI:

  • Altere a classe pai da classe à qual a instância pertence.
  • Adicione ou remova propriedades.
  • Alterar tipos de propriedade.
  • Adicionar ou remover qualificadores Key ou Indexed.
  • Adicione ou remova qualificadores Singleton, Dynamic ou Abstract.

O exemplo de código a seguir combina os exemplos de código discutidos no procedimento anterior para mostrar como criar uma instância usando a API do WMI.

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