IWbemServices::ExecQueryAsync 方法 (wbemcli.h)

IWbemServices::ExecQueryAsync 方法执行查询以异步检索对象。

语法

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

参数

[in] strQueryLanguage

包含 Windows Management Instrumentation (WMI) 支持的查询语言之一的有效 BSTR 。 这必须是“WQL”。

[in] strQuery

包含查询文本的有效 BSTR 。 这不能为 NULL。 实现实例提供程序时,提供程序可能会拒绝查询,因为它太复杂。 当提供程序确定查询过于复杂时,WMI 可以使用简单查询重试提供程序,或者选择检索和枚举查询实例的超集。

若要详细了解如何生成 WMI 查询字符串,请查看使用 WQL 进行查询WQL 参考。

[in] lFlags

此参数的取值可为下列值之一:

WBEM_FLAG_USE_AMENDED_QUALIFIERS

如果设置了此标志,WMI 将检索存储在当前连接区域设置的本地化命名空间中的修改后的限定符。 如果未设置,则仅检索存储在直接命名空间中的限定符。

WBEM_FLAG_BIDIRECTIONAL

此标志使 WMI 保留指向枚举对象的指针,直到客户端释放枚举器。

WBEM_FLAG_SEND_STATUS

此标志向 WMI 注册请求,以通过客户端实现 IWbemObjectSink::SetStatus 接收中间状态报告。 提供程序实现必须支持中间状态报告才能更改此标志。

WBEM_FLAG_ENSURE_LOCATABLE

此标志确保返回的对象中有足够的信息,以便系统属性(如 __PATH__RELPATH__SERVER)为非 NULL

WBEM_FLAG_PROTOTYPE

此标志用于获取原型。 它不执行查询,但返回类似于典型结果对象的 对象。

WBEM_FLAG_DIRECT_READ

此标志导致直接访问指定的类的提供程序,而不考虑其父类或子类。

[in] pCtx

通常 为 NULL。 否则,这是指向 IWbemContext 对象的指针,提供程序可以使用该对象返回请求的类或实例。 必须在提供程序的文档中指定上下文对象中的值。 有关此参数的详细信息,请参阅 调用 WMI

[in] pResponseHandler

指向 调用方 IWbemObjectSink 实现的指针。 当查询结果集中的对象变得可用时,此处理程序接收这些对象。 如果返回任何错误代码,则不使用提供的 IWbemObjectSink 指针。 如果返回 WBEM_S_NO_ERROR ,则调用用户的 IWbemObjectSink 实现来指示操作的结果。 Windows Management Instrumentation (WMI) 调用 IWbemObjectSink::Indicate 和对象任意次数,然后调用 IWbemObjectSink::SetStatus 以指示最终状态。

WMI 仅在WBEM_S_NO_ERROR返回时调用指针的 AddRef。 当错误代码返回时,引用计数与输入时相同。 有关异步调用方法的详细说明,请参阅 调用方法

返回值

此方法返回指示方法调用状态的 HRESULT。 以下列表列出了 HRESULT 中包含的值。

发生故障时,可以从 COM 函数 GetErrorInfo 获取信息。

其他错误代码将返回到 由 pResponseHandler 参数指定的对象接收器。

如果网络问题导致你失去与 WMI 的远程连接,可能会返回特定于 COM 的错误代码。

完成后,实例提供程序可以使用 ExecQueryAsync 中的返回代码或通过 pResponseHandler 调用 SetStatus 来报告成功或失败。 如果选择调用 SetStatus,则通过 pResponseHandler 发送的返回代码优先。

注解

可在 WQL 查询中使用的 AND 和 OR 关键字存在数量限制。 复杂查询中使用大量的 WQL 关键字可能导致 WMI 返回 WBEM_E_QUOTA_VIOLATION 错误代码作为 HRESULT 值。 WQL 关键字的限制取决于查询的复杂程度。

可以调用调用方 IWbemObjectSink::Indicate 方法来报告间歇性状态。 调用 IWbemObjectSink::SetStatus 方法以指示结果集的结束。

当提供程序不支持查询处理时,WMI 可以支持它。 但是,查询处理的提供程序实现可能比 WMI 版本更高效。 若要支持查询,实例提供程序必须实现 ExecQueryAsync 方法。 如果提供程序支持 ExecQueryAsync,则 WMI 通过 strQuery 参数将简单的一元 SELECT 查询直接发送到提供程序,提供程序必须分析查询并返回相关实例。 提供程序必须分析查询,因为 WMI 不会修改查询,即使查询是用 WQL 编写的。

若要使用 WMI 进行查询处理,请不要在__InstanceProviderRegistration中设置 QuerySupportLevels 属性。 执行此操作时,WMI 会调用 CreateInstanceEnumAsync 的实现并发布筛选结果,以便调用方仅获取满足查询条件的实例。

以下示例演示 ExecQueryAsync 的典型实例提供程序实现。 调用 IWbemObjectSink::SetStatus 方法以指示结果集的结束。 也可以调用它,而无需对 IWbemObjectSink::指示 是否发生错误条件。

由于回调可能不会在客户端要求的相同身份验证级别返回,因此建议使用半同步通信而不是异步通信。 如果需要异步通信,请参阅 调用方法

有关详细信息,请参阅 IWbemServices::ExecQuery调用方法

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

在前面的示例中,实例提供程序从 WMI 获取线程以执行必要的同步操作。 可以调用接收器 AddRef 方法并创建另一个线程来传递结果集中的对象。 创建另一个线程允许当前线程返回到 WMI,而不会耗尽线程池。 提供程序选择单线程设计还是双线程设计取决于提供程序计划使用 WMI 线程的时间长度。 没有固定的规则。 试验可以帮助你确定设计如何影响 WMI 性能。

注意 当提供程序实现 ExecQueryAsync 时,默认情况下,它们应基于查询返回正确的结果集。 如果提供程序无法轻松返回正确的结果集,它可能会返回结果的超集,并请求 WMI 在将对象传送到客户端之前执行后筛选,以确保结果集正确。 为此,提供程序在提供给其 ExecQueryAsync 实现的接收器上调用 SetStatus,并使用以下标志。
 
// The pSink variable is of type IWbemObjectSink*
pSink->SetStatus(WBEM_STATUS_REQUIREMENTS,
    WBEM_REQUIREMENTS_START_POSTFILTER, 0, 0);
注意 随后发送到 WMI 服务的任何对象都将被筛选。 提供程序可以通过使用以下调用在中流中关闭后期筛选。
 
// The pSink variable is of type IWbemObjectSink*
pSink->SetStatus(WBEM_STATUS_REQUIREMENTS, 
    WBEM_REQUIREMENTS_STOP_POSTFILTER, 0, 0);

要求

   
最低受支持的客户端 Windows Vista
最低受支持的服务器 Windows Server 2008
目标平台 Windows
标头 wbemcli.h (包括 Wbemidl.h)
Library 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

另请参阅

调用方法

IWbemObjectSink::SetStatus

IWbemServices

IWbemServices::ExecQuery

使用 WQL 查询