IWbemObjectSink インターフェイス
IWbemObjectSink インターフェイスは、WMI プログラミング モデル内のすべての種類の通知を受信できるシンク インターフェイスを作成します。 クライアントは、IWbemServices の 非同期メソッドの結果と、特定の種類のイベント通知の両方を受信するために、このインターフェイスを実装する必要があります。 プロバイダーはこのインターフェイスを使用しますが、WMI にイベントとオブジェクトを提供するためにこのインターフェイスを実装しません。
プロバイダーは通常、WMI によって提供される実装を呼び出します。 このような場合は、Indicate を呼び出して WMI サービスにオブジェクトを提供します。 その後、SetStatus を呼び出して、通知シーケンスの終了を示します。 SetStatus を呼び出して、シンクにオブジェクトがない場合のエラーを示すこともできます。
WMI の非同期クライアントをプログラミングするときに、ユーザーは実装を提供します。 WMI はメソッドを呼び出してオブジェクトを配信し、結果の状態を設定します。
注意
クライアント アプリケーションが 2 つの異なる重複する非同期呼び出しで同じシンク インターフェイスを渡す場合、WMI ではコールバックの順序は保証されません。 重複する非同期呼び出しを行うクライアント アプリケーションは、異なるシンク オブジェクトを渡すか、呼び出しをシリアル化する必要があります。
注意
シンクへのコールバックはクライアントが必要とするのと同じ認証レベルでは返されない可能性があるため、非同期ではなく半同期通信を使用することをお勧めします。 詳細については、「メソッドの呼び出し」を参照してください。
メンバー
IWbemObjectSink インターフェイスには、次の種類のメンバーがあります。
メソッド
IWbemObjectSink インターフェイスには、次のメソッドがあります。
メソッド | 説明 |
---|---|
Indicate | 通知オブジェクトを受信します。 |
SetStatus | 通知シーケンスの終了を示すか、シンクに他の状態コードを送信するために、ソースによって呼び出されます。 |
解説
イベント サブスクリプション シンク (IWbemObjectSink または IWbemEventSink) を実装するときは、シンク オブジェクトの Indicate メソッドまたは SetStatus メソッド内から WMI を呼び出さないでください。 たとえば、IWbemServices::CancelAsyncCall を呼び出して Indicate の実装内からシンクを取り消すと、WMI の状態が妨げられる可能性があります。 イベント サブスクリプションを取り消すには、フラグを設定し、IWbemServices::CancelAsyncCall を別のスレッドまたはオブジェクトから呼び出します。 オブジェクト、列挙型、クエリの取得など、イベント シンクに関連しない実装の場合は、WMI にコールバックできます。
イベント通知を配信する WMI スレッドはシンク オブジェクトの処理が完了するまで他の処理を実行できないため、シンクの実装ではイベント通知を 100 ミリ秒内で処理する必要があります。 通知で大量の処理が必要な場合、シンクでは内部キューを別のスレッドで使用して処理を操作できます。
例
次のコード例は、オブジェクト シンクの単純な実装です。 このサンプルを 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 |
Header |
|
ライブラリ |
|
[DLL] |
|