Win32 API 日本語リファレンス
ホームSystem.Wmi › IWbemObjectSink

IWbemObjectSink

COM
IID7c857801-7381-11cf-884d-00aa004b2e24継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

IWbemObjectSink インターフェイスは、WMI プログラミングモデル内のあらゆる種類の通知を受け取ることができるシンクインターフェイスを作成します。

解説(Remarks)

イベントサブスクリプション用のシンク(IWbemObjectSink または IWbemEventSink)を実装する場合、シンクオブジェクトの Indicate メソッドや SetStatus メソッドの中から WMI を呼び出さないでください。たとえば、Indicate の実装内からシンクをキャンセルするために IWbemServices::CancelAsyncCall を呼び出すと、WMI の状態に支障をきたすおそれがあります。イベントサブスクリプションをキャンセルするには、フラグを設定したうえで、別のスレッドまたは別のオブジェクトから IWbemServices::CancelAsyncCall を呼び出してください。オブジェクト、列挙、クエリの取得など、イベントシンクに関連しない実装では、WMI をコールバックしてもかまいません。

イベント通知を配信する WMI のスレッドは、シンクオブジェクトが処理を完了するまで他の作業を行えないため、シンクの実装ではイベント通知を 100 ミリ秒以内に処理してください。通知に大量の処理が必要な場合は、シンク側で内部キューを使用し、別のスレッドに処理を任せることができます。

Examples

次のコード例は、オブジェクトシンクの単純な実装です。このサンプルは、 IWbemServices::ExecQueryAsync または IWbemServices::CreateInstanceEnumAsync と組み合わせて、返されるインスタンスを受け取るために使用できます。

C++
#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;
}

メソッド 2

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 3 HRESULT Indicate(INT lObjectCount, IWbemClassObject** apObjArray)

通知を提供するために、ソースから呼び出されます。

lObjectCountINTin後続のポインター配列に含まれるオブジェクトの数。
apObjArrayIWbemClassObject**inIWbemClassObject インターフェイスへのポインターの配列。配列のメモリ自体は読み取り専用であり、メソッドの呼び出し元が所有します。これは入力パラメーターであるため、メソッドが戻った後もオブジェクトを使用する場合は、COM の規則に従い、実装側で配列内の任意のオブジェクトポインターに対して IWbemClassObject::AddRef を呼び出して保持しておくことができます。オブジェクトを Indicate の呼び出し中にのみ使用する場合は、各オブジェクトポインターに対して AddRef を呼び出す必要はありません。

戻り値

このメソッドは、メソッド呼び出しの状態を示す HRESULT を返します。次の一覧は、HRESULT に格納される値を示します。

解説(Remarks)

イベントサブスクリプション用のシンク(IWbemObjectSink または IWbemEventSink)を実装する場合、シンクオブジェクトの Indicate メソッドの中から WMI を呼び出さないでください。たとえば、Indicate の実装内から IWbemServices::CancelAsyncCall を呼び出すと、WMI の状態に支障をきたすおそれがあります。イベントサブスクリプションをキャンセルするには、フラグを設定したうえで、別のスレッドまたは別のオブジェクトから IWbemServices::CancelAsyncCall を呼び出してください。オブジェクト、列挙、クエリの取得など、イベントシンクに関連しない実装では、WMI をコールバックしてもかまいません。

イベント通知を配信する WMI のスレッドは、シンクオブジェクトが処理を完了するまで他の作業を行えないため、シンクの実装ではイベント通知を 100 ミリ秒以内に処理してください。通知に大量の処理が必要な場合は、シンク側で内部キューを使用し、別のスレッドに処理を任せることができます。

イベントプロバイダーがイベントを提供するために Indicate を呼び出したとき、その呼び出しが WBEM_E_SERVER_TOO_BUSY で失敗することがあります。プロバイダーは、これに対してイベントを再送出することで対応できます。

メモ シンクへのコールバックは、クライアントが要求する認証レベルと同じレベルで返されるとは限らないため、非同期通信ではなく半同期(semisynchronous)通信を使用することをお勧めします。詳細については、Calling a Method を参照してください。
vtbl 4 HRESULT SetStatus(INT lFlags, HRESULT hResult, LPWSTR strParam, IWbemClassObject* pObjParam)

通知シーケンスの終了を示すため、またはその他の状態コードをシンクに送るために、ソースから呼び出されます。

lFlagsINTin

状態情報のビットマスク。操作の状態は、hResult パラメーターを調べることで取得できます。

WBEM_STATUS_COMPLETE

操作が完了しました。

WBEM_STATUS_PROGRESS

操作はまだ進行中です。

WBEM_STATUS_REQUIREMENTS

ポストフィルター処理の有効化に使用されます。

hResultHRESULTinこのパラメーターには、非同期操作または通知の HRESULT が設定されます。エラーが発生した場合はエラーコードが、そうでない場合は非同期呼び出しの進捗状況が設定されます。
strParamLPWSTRin元の非同期操作が文字列を返す場合、読み取り専用の BSTR へのポインターを受け取ります。たとえば PutInstanceAsync を使用した場合、このパラメーターに新しく作成されたインスタンスのオブジェクトパスが設定された状態で SetStatus が呼び出されます。
pObjParamIWbemClassObject*in複雑なエラーオブジェクトまたは状態オブジェクトが返される場合、これにはエラーオブジェクトへのポインターが格納されます。 SetStatus が戻った後もそのオブジェクトが必要な場合、呼び出されたオブジェクトは、戻る前にそのポインターに対して AddRef メソッドを使用する必要があります。

戻り値

このメソッドは、メソッド呼び出しの状態を示す HRESULT を返します。次の一覧は、HRESULT に格納される値を示します。

解説(Remarks)

イベントサブスクリプション用のシンク(IWbemObjectSink または IWbemEventSink)を実装する場合、シンクオブジェクトの SetStatus メソッドの中から WMI を呼び出さないでください。たとえば、SetStatus の実装内から IWbemServices::CancelAsyncCall を呼び出すと、WMI の状態に支障をきたすおそれがあります。イベントサブスクリプションをキャンセルするには、フラグを設定したうえで、別のスレッドまたは別のオブジェクトから IWbemServices::CancelAsyncCall を呼び出してください。オブジェクト、列挙、クエリの取得など、イベントシンクに関連しない実装では、WMI をコールバックしてもかまいません。

イベント通知を配信する WMI のスレッドは、シンクオブジェクトが処理を完了するまで他の作業を行えないため、シンクの実装ではイベント通知を 100 ミリ秒以内に処理してください。通知に大量の処理が必要な場合は、シンク側で内部キューを使用し、別のスレッドに処理を任せることができます。オブジェクト、列挙、クエリの取得など、イベントシンクに関連しない実装では、WMI をコールバックしてもかまいません。

クライアント側の SetStatus 実装を通じて途中経過の状態更新を受け取るには、プロバイダーまたはサービスのメソッドを呼び出す際に WBEM_FLAG_SENT_STATUS を指定する必要があります。正確な状態は、hResult の HIWORD 値と LOWORD 値をそれぞれ調べることで判断できます。LOWORD(hResult)の値にはこれまでに進んだ量が、HIWORD(hResult)の値には全体量が格納されます。

プロバイダーまたはサービスのメソッドを呼び出す際に WBEM_FLAG_SEND_STATUS を指定しない場合、 SetStatus の呼び出しはちょうど 1 回だけ行われることが保証されます。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

#define global IID_IWbemObjectSink "{7C857801-7381-11CF-884D-00AA004B2E24}"
#usecom global IWbemObjectSink IID_IWbemObjectSink "{}"
#comfunc global IWbemObjectSink_Indicate   3 int,sptr
#comfunc global IWbemObjectSink_SetStatus  4 int,int,wstr,sptr
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。