Интерфейс IWbemObjectSink

Интерфейс IWbemObjectSink создает интерфейс приемника, который может получать все типы уведомлений в модели программирования WMI. Клиенты должны реализовать этот интерфейс для получения как результатов асинхронных методовIWbemServices, так и определенных типов уведомлений о событиях. Поставщики используют, но не реализуют этот интерфейс для предоставления событий и объектов WMI.

Как правило, поставщики вызывают реализацию, предоставленную им WMI. В таких случаях вызовите команду Показать , чтобы предоставить объекты службе WMI. После этого вызовите SetStatus , чтобы указать конец последовательности уведомлений. Можно также вызвать SetStatus , чтобы указать ошибки, когда в приемнике нет объектов.

При программировании асинхронных клиентов WMI пользователь предоставляет реализацию. WMI вызывает методы для доставки объектов и установки состояния результата.

Примечание

Если клиентское приложение передает один и тот же интерфейс приемника в двух разных перекрывающихся асинхронных вызовах, WMI не гарантирует порядок обратного вызова. Клиентские приложения, выполняющие перекрывающиеся асинхронные вызовы, должны либо передавать разные объекты приемника, либо сериализовать свои вызовы.

Примечание

Так как обратный вызов в приемник может быть возвращен не на том же уровне проверки подлинности, который требуется клиенту, рекомендуется использовать полусинхронный режим вместо асинхронного взаимодействия. Дополнительные сведения см. в разделе Вызов метода .

Элементы

Интерфейс IWbemObjectSink имеет следующие типы элементов:

Методы

Интерфейс IWbemObjectSink содержит следующие методы.

Метод Описание
Указать Получает объекты уведомлений.
SetStatus Вызывается источниками для указания конца последовательности уведомлений или для отправки других кодов состояния в приемник.

Комментарии

При реализации приемника подписки на события (IWbemObjectSink или IWbemEventSink) не вызывайте WMI из методов Indicate или SetStatus в объекте приемника. Например, вызов IWbemServices::CancelAsyncCall для отмены приемника из реализации Параметра Указывает может помешать состоянию WMI. Чтобы отменить подписку на события, установите флаг и вызовите IWbemServices::CancelAsyncCall из другого потока или объекта. Для реализаций, не связанных с приемником событий, таких как объект, перечисление и извлечение запросов, можно вызвать обратно в WMI.

Реализации приемника должны обрабатывать уведомление о событии в пределах 100 MSEC, так как поток WMI, доставляющий уведомление о событии, не может выполнять другие действия, пока объект приемника не завершит обработку. Если уведомление требует большого объема обработки, приемник может использовать внутреннюю очередь для обработки другим потоком.

Примеры

Следующий пример кода представляет собой простую реализацию приемника объектов. Этот пример можно использовать с IWbemServices::ExecQueryAsync или IWbemServices::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 для WMI

Выполнение асинхронного вызова с помощью C++

Настройка безопасности при асинхронном вызове

Получение событий за период действия приложения