物理コンシューマーの実装
物理コンシューマーは、IWbemUnboundObjectSink インターフェイスを実装する COM オブジェクトです。 WMI では、1 つ以上のイベントに応答して、物理コンシューマーを読み込み、IWbemUnboundObjectSink を介してイベントを渡します。 永続コンシューマーには、特別なセキュリティ要件があります。 詳細については、「WMI イベントのセキュリティ保護」を参照してください。
次の手順では、永続イベント コンシューマーの物理コンシューマーを実装する方法について説明します。
永続イベント コンシューマーの物理コンシューマーを実装するには、次の手順を行います
COM オブジェクトを作成します。
物理コンシューマーは、COM プロトコルを使用して、ローカル サーバーまたはリモート サーバーとして実装する必要があります。
同期または非同期のどちらのイベント通知をサポートするかを決定します。
非同期イベント通知の場合、送信スレッドと受信スレッドは無関係です。 そのため、イベントを受信するために登録されたコンシューマーへ WMI から通知が配信されている間は、WMI もイベント プロバイダーもブロックされません。 非同期配信の欠点は、プロバイダーによってイベントが生成されてからコンシューマーがイベントを受信するまでの時間にコンテキスト切り替えが発生することです。 非同期的な作業の詳細については、Microsoft Windows ソフトウェア開発キット (SDK) の COM セクションで、COM の基礎に関するトピックを参照してください。 コンテキスト切り替えに関する詳細については、Windows SDK の DLL、プロセス、スレッドに関するセクションで、「コンテキスト切り替え」トピックを参照してください。
注意
シンクへのコールバックはクライアントが必要とするのと同じ認証レベルでは返されない可能性があるため、非同期ではなく半同期通信を使用することをお勧めします。 詳細については、メソッドの呼び出しに関するページを参照してください。
同期通知の場合、イベント プロバイダーから WMI へイベントが配信されたときと同じスレッド上で、WMI から通知が配信されます。 この場合、イベント プロバイダーから通知が送信されると、WMI から通知が配信されるまで、そのイベント プロバイダーは WMI によってブロックされます。 同期通知のサポートについては、コンシューマーが 100 ミリ秒以下の超高速なイベント処理能力を備えている場合にのみ検討すべきです。 イベントの処理に非常に長い時間がかかる同期コンシューマーは、他のすべてのコンシューマーへのイベントの配信に深刻な遅延をもたらす可能性があります。 また、プロバイダーを誤ってブロックしてしまう可能性もあります。 詳細については、「論理コンシューマーを使用してイベント フィルターをバインドする」を参照してください。
IWbemUnboundObjectSink::IndicateToConsumer 関数を実装します。
WMI では、IndicateToConsumer 関数を使用して、同期通信と非同期通信の両方で、必要なポインターとイベントを物理コンシューマーに渡します。 IndicateToConsumer の実装には、イベントへの応答に必要なすべてのコードが含まれている必要があります。
一時的なイベント コンシューマーとは異なり、WMI への接続のために IWbemLocator インターフェイスを呼び出す必要はありません。 代わりに、WMI では、コンシューマーを指すポインターを検索するときは、イベント コンシューマー プロバイダーを使用します。 詳細については、「イベント コンシューマー プロバイダーの作成」を参照してください。
ただし、WMI にコールバックする場合は、IWbemLocator インターフェイスと IWbemServices インターフェイスを使用します。 WMI への接続は、COM オブジェクトの初期化プロセス中に行うというのが従来の方法です。 詳細については、「WMI アプリケーションまたはスクリプトの作成」を参照してください。
物理コンシューマーをインプロセス COM サーバーとして実装して、初期化プロセスとは別に WMI に接続する場合は、CLSID_WbemAdministrativeLocator クラス識別子を使用して、CoCreateInstance への呼び出しで IWbemLocator インターフェイスにアクセスする必要があります。
次の例は、CLSID_WbemAdministrativeLocator クラス識別子を使用して IWbemLocator インターフェイスにアクセスする方法を示しています。
IWbemLocator *pLoc = 0; DWORD dwRes = CoCreateInstance(CLSID_WbemAdministrativeLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
IWbemLocator インターフェイスを使用すると、特定のホスト コンピューターで、WMI を指す初期名前空間ポインターを取得できます。 CoCreateInstance 呼び出しで CLSID_WbemAdministrativeLocator 識別子を使用しないと、"アクセスが拒否されました" というエラーが発生します。
通常の状況では、WMI からクライアントに非同期イベントが 1 つずつ配信されます。 ただし、イベントの到着と同時にクライアントが非同期イベント通知を受信できない場合、WMI では、1 回の呼び出しへのイベントの自動バッチ処理が開始します。 高スループットのシナリオではよくあることですが、ラウンド トリップ時間が問題となっている場合は、自動バッチ処理が便利です。 ただし、クライアントまたはネットワークの帯域幅で障害が発生している場合は、バッチ処理を行ってもシステム パフォーマンスは向上しません。