IWbemObjectSink 接口

IWbemObjectSink 接口创建接收器接口,可以接收 WMI 编程模型中所有类型的通知。 客户端必须实现此接口才能接收 IWbemServices异步方法的结果和特定类型的事件通知。 提供程序使用此接口来向 WMI 提供事件和对象,但它不实现此接口。

通常,提供程序会调用 WMI 向其提供的实现。 在这些情况下,需调用 Indicate 来向 WMI 服务提供对象。 之后,调用 SetStatus 来指示通知序列的结束。 在接收器没有任何对象时,还可以调用 SetStatus 来指示错误。

在对 WMI 的异步客户端进行编程时,用户会提供实现。 WMI 调用方法来传递对象并设置结果状态。

注意

如果客户端应用程序在两个不同的重叠异步调用中传递相同的接收器接口,WMI 无法保证回调顺序。 进行重叠异步调用的客户端应用程序应传递不同的接收器对象,或将其调用序列化。

注意

由于可能不会以客户端要求的相同身份验证级别返回对接收器的回调,因此建议使用半同步通信而不是异步通信。 有关详细信息,请参阅调用方法

成员

IWbemObjectSink 接口具有以下类型的成员:

方法

IWbemObjectSink 接口具有以下方法。

方法 说明
Indicate 接收通知对象。
SetStatus 由源调用以指示通知序列的结束,或将其他状态代码发送到接收器。

备注

实现事件订阅接收器(IWbemObjectSink 或 IWbemEventSink)时,不要从接收器对象上的 IndicateSetStatus 方法中调用 WMI。 例如,如果调用 IWbemServices::CancelAsyncCall 来从 Indicate 的实现中取消接收器,可能会干扰 WMI 状态。 若要取消事件订阅,请设置一个标志,并从另一线程或对象调用 IWbemServices::CancelAsyncCall。 对于对象、枚举和查询检索等与事件接收器无关的实现,可以回调到 WMI。

接收器实现应在 100 MSEC 内处理事件通知,因为在接收器对象完成处理之前,传递事件通知的 WMI 线程无法执行其他工作。 如果通知需要大量处理,接收器可使用另一个线程的内部队列来进行处理。

示例

以下代码示例是对象接收器的简单实现。 此示例可与 IWbemServices::ExecQueryAsyncIWbemServices::CreateInstanceEnumAsync 一起使用来接收返回的实例:

#include <iostream>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

class QuerySink : public IWbemObjectSink
{
    LONG m_lRef;
    bool bDone; 

public:
    QuerySink() { m_lRef = 0; }
   ~QuerySink() { bDone = TRUE; }

    virtual ULONG STDMETHODCALLTYPE AddRef();
    virtual ULONG STDMETHODCALLTYPE Release();        
    virtual HRESULT STDMETHODCALLTYPE 
        QueryInterface(REFIID riid, void** ppv);

    virtual HRESULT STDMETHODCALLTYPE Indicate( 
            /* [in] */
            LONG lObjectCount,
            /* [size_is][in] */
            IWbemClassObject __RPC_FAR *__RPC_FAR *apObjArray
            );
        
    virtual HRESULT STDMETHODCALLTYPE SetStatus( 
            /* [in] */ LONG lFlags,
            /* [in] */ HRESULT hResult,
            /* [in] */ BSTR strParam,
            /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
            );
};


ULONG QuerySink::AddRef()
{
    return InterlockedIncrement(&m_lRef);
}

ULONG QuerySink::Release()
{
    LONG lRef = InterlockedDecrement(&m_lRef);
    if(lRef == 0)
        delete this;
    return lRef;
}

HRESULT QuerySink::QueryInterface(REFIID riid, void** ppv)
{
    if (riid == IID_IUnknown || riid == IID_IWbemObjectSink)
    {
        *ppv = (IWbemObjectSink *) this;
        AddRef();
        return WBEM_S_NO_ERROR;
    }
    else return E_NOINTERFACE;
}


HRESULT QuerySink::Indicate(long lObjCount, IWbemClassObject **pArray)
{
    for (long i = 0; i < lObjCount; i++)
    {
        IWbemClassObject *pObj = pArray[i];

        // ... use the object.

        // AddRef() is only required if the object will be held after
        // the return to the caller.
    }

    return WBEM_S_NO_ERROR;
}

HRESULT QuerySink::SetStatus(
            /* [in] */ LONG lFlags,
            /* [in] */ HRESULT hResult,
            /* [in] */ BSTR strParam,
            /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
        )
{
    printf("QuerySink::SetStatus hResult = 0x%X\n", hResult);
    return WBEM_S_NO_ERROR;
}

要求

要求
最低受支持的客户端
Windows Vista
最低受支持的服务器
Windows Server 2008
标头
Wbemcli.h(包括 Wbemidl.h)

Wbemuuid.lib
DLL
Fastprox.dll

另请参阅

COM API for WMI

使用 C++ 进行异步调用

设置异步调用的安全性

在应用程序持续时间内接收事件