Partilhar via


Método IWbemServices::ExecQueryAsync (wbemcli.h)

O método IWbemServices::ExecQueryAsync executa uma consulta para recuperar objetos de forma assíncrona.

Sintaxe

HRESULT ExecQueryAsync(
  [in] const BSTR      strQueryLanguage,
  [in] const BSTR      strQuery,
  [in] long            lFlags,
  [in] IWbemContext    *pCtx,
  [in] IWbemObjectSink *pResponseHandler
);

Parâmetros

[in] strQueryLanguage

BSTR válido que contém uma das linguagens de consulta compatíveis com a WMI (Instrumentação de Gerenciamento do Windows). Isso deve ser "WQL".

[in] strQuery

BSTR válido que contém o texto da consulta. Isso não pode ser NULL. Quando você implementa um provedor de instância, seu provedor pode recusar a consulta porque ela é muito complexa. Quando um provedor determina que uma consulta é muito complexa, o WMI pode repetir o provedor com uma consulta simples ou optar por recuperar e enumerar o superconjunto das instâncias de consulta.

Para obter mais informações sobre como criar cadeias de caracteres de consulta do WMI, veja Como consultar com WQL e a referência da WQL.

[in] lFlags

Esse parâmetro pode usar um dos valores a seguir.

WBEM_FLAG_USE_AMENDED_QUALIFIERS

Se esse sinalizador estiver definido, o WMI recuperará os qualificadores alterados armazenados no namespace localizado da localidade da conexão atual. Se não estiver definido, somente os qualificadores armazenados no namespace imediato serão recuperados.

WBEM_FLAG_BIDIRECTIONAL

Esse sinalizador faz com que o WMI mantenha ponteiros para objetos da enumeração até que o cliente libere o enumerador.

WBEM_FLAG_SEND_STATUS

Esse sinalizador registra uma solicitação com o WMI para receber relatórios de status intermediários por meio da implementação do cliente de IWbemObjectSink::SetStatus. A implementação do provedor deve dar suporte a relatórios de status intermediários para que esse sinalizador seja alterado.

WBEM_FLAG_ENSURE_LOCATABLE

Esse sinalizador garante que os objetos retornados tenham informações suficientes para que as propriedades do sistema, como __PATH, __RELPATH e __SERVER, não sejam NULL.

WBEM_FLAG_PROTOTYPE

Este sinalizador é usado para criação de protótipos. Ele não executa a consulta, mas retorna um objeto que se parece com um objeto de resultado típico.

WBEM_FLAG_DIRECT_READ

Esse sinalizador faz com que o acesso direto ao provedor para a classe especificada sem levar em conta sua classe pai ou subclasses.

[in] pCtx

Normalmente NULL. Caso contrário, esse é um ponteiro para um objeto IWbemContext que o provedor pode usar para retornar as classes ou instâncias solicitadas. Os valores no objeto de contexto devem ser especificados na documentação do provedor. Para obter mais informações sobre esse parâmetro, consulte Fazendo chamadas para WMI.

[in] pResponseHandler

Ponteiro para a implementação do chamador de IWbemObjectSink. Esse manipulador recebe os objetos no conjunto de resultados da consulta conforme eles ficam disponíveis. Se algum código de erro for retornado, o ponteiro IWbemObjectSink fornecido não será usado. Se WBEM_S_NO_ERROR for retornado, a implementação IWbemObjectSink do usuário será chamada para indicar o resultado da operação. A WMI (Instrumentação de Gerenciamento do Windows) chama IWbemObjectSink::Indicate com os objetos várias vezes, seguida por uma única chamada para IWbemObjectSink::SetStatus para indicar o status final.

O WMI só chama AddRef para o ponteiro quando WBEM_S_NO_ERROR retorna. Quando um código de erro retorna, a contagem de referência é a mesma que na entrada. Para obter uma explicação detalhada dos métodos de chamada assíncrona, consulte Chamando um método.

Retornar valor

Esse método retorna um HRESULT que indica o status da chamada de método. A lista a seguir lista o valor contido em um HRESULT.

Quando há uma falha, você pode obter informações da função COM GetErrorInfo.

Outros códigos de erro são retornados para o coletor de objeto especificado pelo parâmetro pResponseHandler .

Códigos de erro específicos de COM poderão ser retornados se problemas de rede fizerem com que você perca a conexão remota com o WMI.

Quando concluído, um provedor de instância pode relatar êxito ou falha com o código de retorno de ExecQueryAsync ou por meio de uma chamada para SetStatus feita por meio de pResponseHandler. Se você optar por chamar SetStatus, o código de retorno enviado por meio de pResponseHandler terá precedência.

Comentários

Existem limites no número de palavras-chave AND e OR que podem ser usadas nas consultas WQL. Um grande número de palavras-chave da WQL usadas em uma consulta complexa pode fazer com que o WMI retorne o código de erro WBEM_E_QUOTA_VIOLATION como um valor HRESULT. O limite de palavras-chave WQL depende da complexidade da consulta.

O método IWbemObjectSink::Indicate do chamador pode ser chamado para relatar status intermitentes. O método IWbemObjectSink::SetStatus é chamado para indicar o final do conjunto de resultados.

Quando um provedor não dá suporte ao processamento de consulta, o WMI pode dar suporte a ele. No entanto, uma implementação do provedor de processamento de consulta provavelmente é mais eficiente do que a versão do WMI. Para dar suporte a consultas, seu provedor de instância deve implementar o método ExecQueryAsync . Se um provedor der suporte a ExecQueryAsync, o WMI enviará uma consulta SELECT unária simples diretamente para o provedor por meio do parâmetro strQuery e o provedor deverá analisar a consulta e retornar as instâncias relevantes. O provedor deve analisar a consulta porque o WMI não modifica a consulta, mesmo quando a consulta é gravada no WQL.

Para usar o WMI para processamento de consulta, não defina a propriedade QuerySupportLevels em seu __InstanceProviderRegistration. Quando você faz isso, o WMI chama sua implementação de CreateInstanceEnumAsync e post filtra os resultados para que o chamador obtenha apenas as instâncias que atendem aos critérios de consulta.

O exemplo a seguir mostra uma implementação típica do provedor de instância de ExecQueryAsync. O método IWbemObjectSink::SetStatus é chamado para indicar o final do conjunto de resultados. Ele também pode ser chamado sem nenhuma chamada intervindo para IWbemObjectSink::Indique se ocorrem condições de erro.

Como o retorno de chamada pode não ser retornado no mesmo nível de autenticação exigido pelo cliente, é recomendável que você use a comunicação semissíncrona em vez de assíncrona. Se você precisar de comunicação assíncrona, consulte Chamando um método.

Para obter mais informações, consulte IWbemServices::ExecQuery e Chamando um método.

HRESULT CStdProvider::ExecQueryAsync( 
            /* [in] */ BSTR strQueryLanguage,
            /* [in] */ BSTR strQuery,
            /* [in] */ long lFlags,
            /* [in] */ IWbemContext __RPC_FAR *pCtx,
            /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler
            )
{
   IWbemClassObject *pClass = 0;

// Parse the query.
//   You must implement ParseQuery().
    if (!ParseQuery(strQuery))  return WBEM_E_PROVIDER_NOT_CAPABLE;   

// Assume there is an IWbemServices pointer (m_pSvc) available to 
// retrieve the class definition.
    
    HRESULT hRes = m_pSvc->GetObject(L"ClassName", 0, NULL, &pClass, 0);
    if (FAILED(hRes))
        return hRes;

// Call a method to determine number of instances returned.
// You need to implement the GetNumberInst function.
    int iNumInst = GetNumberInst();

// Now loop through the private source and create each   
// instance which is part of the result set of the query.
    for (int iCnt = 0 ; iCnt < iNumInst ; iCnt++)
    {
// Prepare an empty object to receive the class definition.
         IWbemClassObject *pNextInst = 0;
         hRes = pClass->SpawnInstance(0, &pNextInst);

// Create the instance.
//   You must implement FillInst().
         /*FillInst(pNextInst, iCnt);*/ 

// Deliver the class to WMI.
         pResponseHandler->Indicate(1, &pNextInst);
         pNextInst->Release( );
    }

// Clean up memory
    pClass->Release();
  
// Send finish message to WMI.

    pResponseHandler->SetStatus(0, hRes, 0, 0);

    return hRes;
}

No exemplo anterior, o provedor de instância adquire um thread do WMI para executar as operações de sincronização necessárias. Você pode chamar o método AddRef do coletor e criar outro thread para entregar os objetos no conjunto de resultados. A criação de outro thread permite que o thread atual retorne ao WMI sem esgotar o pool de threads. Se o provedor escolhe o design de thread único ou o design de thread duplo depende de quanto tempo o provedor planeja usar o thread WMI. Não há regras fixas. A experimentação pode ajudá-lo a determinar como seu design afeta o desempenho do WMI.

Nota Quando os provedores implementam ExecQueryAsync, eles são esperados por padrão para retornar o conjunto de resultados correto com base na consulta. Se um provedor não puder retornar o conjunto de resultados correto facilmente, ele poderá retornar um superconjunto dos resultados e solicitar que a WMI faça a pós-filtragem antes de entregar os objetos ao cliente para garantir que o conjunto de resultados esteja correto. Para fazer isso, o provedor chama SetStatus no coletor fornecido para sua implementação ExecQueryAsync , com os sinalizadores a seguir.
 
// The pSink variable is of type IWbemObjectSink*
pSink->SetStatus(WBEM_STATUS_REQUIREMENTS,
    WBEM_REQUIREMENTS_START_POSTFILTER, 0, 0);
Nota Todos os objetos enviados posteriormente para o serviço WMI são filtrados. O provedor pode desativar a pós-filtragem no meio do fluxo usando a chamada a seguir.
 
// The pSink variable is of type IWbemObjectSink*
pSink->SetStatus(WBEM_STATUS_REQUIREMENTS, 
    WBEM_REQUIREMENTS_STOP_POSTFILTER, 0, 0);

Requisitos

   
Cliente mínimo com suporte Windows Vista
Servidor mínimo com suporte Windows Server 2008
Plataforma de Destino Windows
Cabeçalho wbemcli.h (inclua Wbemidl.h)
Biblioteca Wbemuuid.lib
DLL Fastprox.dll; Esscli.dll; FrameDyn.dll; FrameDynOS.dll; Ntevt.dll; Stdprov.dll; Viewprov.dll; Wbemcomn.dll; Wbemcore.dll; Wbemess.dll; Wbemsvc.dll; Wmipicmp.dll; Wmidcprv.dll; Wmipjobj.dll; Wmiprvsd.dll

Confira também

Como chamar um método

IWbemObjectSink::SetStatus

IWbemServices

IWbemServices::ExecQuery

Como consultar com WQL