アプリケーションへのプロバイダーの組み込み

インストルメント化するアプリケーションを作成する際は、プロバイダーをアプリケーション自体にコンポーネントとして追加する方法が推奨されています。 この方法により、Windows Management Instrumentation (WMI) は、プログラム API を介して間接的にではなく、サービス プロバイダーと直接やり取りすることができます。 また、WMI からプロバイダーを切り離すことで、WMI の代わりにアプリケーションがプロバイダーの有効期間を制御できるようになります。 WMI プロセス内で動作するプロバイダーの作成については、「プロバイダーを記述して WMI にデータを提供する」を参照してください。 プロバイダーのホスティング モデルとセキュリティ設定の詳細については、「プロバイダーのホスティングとセキュリティ」を参照してください。

次の図は、WMI、分離プロバイダー、アプリケーションの関係を示しています。

WMI、分離プロバイダー、アプリケーション間の関係

分離プロバイダーのメソッドの詳細については、IWbemDecoupledRegistrarIWbemDecoupledBasicEventProvider に関する記事を参照してください。

注意

分離プロバイダーは、インスタンス、メソッド、イベント プロバイダー、イベント コンシューマーをサポートします。 クラスおよびプロパティ プロバイダーはサポートされません。 詳細については、「クラス プロバイダーの記述」および「プロパティ プロバイダーの記述」を参照してください。

 

このトピックのコード例を正しくコンパイルするには、次の参照と #include ステートメントが必要です。

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

以下の手順では、C++ のコード例を使用して、分離プロバイダーをアプリケーションに組み込む方法を説明しています。 登録済みの分離プロバイダーとのみ WMI が対話するように、アプリケーションの初期化メソッドで次の手順を実行します。

分離プロバイダーを C++ アプリケーションに実装するには

  1. 呼び出し元のスレッドで使用する COM ライブラリを初期化します。

    COM ライブラリを初期化する方法を次のコード例に示します。

    HRESULT hr = S_OK ;
    hr = CoInitializeEx (0, COINIT_MULTITHREADED );
    
  2. 既定のプロセス セキュリティ レベルを設定します。

    このレベルにより、他のプロセスがクライアント プロセスの情報にアクセスするために必要なセキュリティ レベルが確立されます。 認証レベルは RPC_C_AUTHN_LEVEL_DEFAULT にする必要があります。 詳細については、「WMI セキュリティの維持」を参照してください。

    次のコード例に、既定のセキュリティ レベルを設定する方法を示します。

    hr = CoInitializeSecurity (NULL, 
        -1, 
        NULL, 
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, 
        EOAC_DYNAMIC_CLOAKING, 
        NULL);
    
    if (FAILED(hr))
    {
      CoUninitialize();
      cout << "Failed to initialize security. Error code = 0x"
           << hex << hr << endl;
      return;
    }
    
  3. 分離プロバイダー レジストラーを登録します。

    次のコード例に、分離プロバイダー レジストラーを登録する方法を示します。

    CLSID CLSID_WbemDecoupledRegistrar;
    IID IID_IWbemDecoupledRegistrar;
    IWbemDecoupledRegistrar *myRegistrar = NULL;
    
    hr = CoCreateInstance(CLSID_WbemDecoupledRegistrar,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_IWbemDecoupledRegistrar,
                          (void**)&myRegistrar);
    if (SUCCEEDED(hr))
    {
        IUnknown *pIUnknown = NULL;
        // CMyProv is the class added for WMI instance / event provider
        HRESULT hr = CMyProv::CreateInstance(NULL,&pIUnknown);
        if ( SUCCEEDED(hr))
        {
            hr = myRegistrar->Register(0,
                NULL,
                NULL,
                NULL,
                L"root\\cimv2",
                L"DecoupledInstanceProvider",
                pIUnknown);
    
                pIUnknown->Release();
        }
    }
    
    if (FAILED (hr))
    {
        if ( myRegistrar )
        {
            myRegistrar->Release () ;
        }
    }
    
  4. 分離イベント プロバイダーを登録します。

    次のコード例に、分離イベント プロバイダーを登録する方法を示します。

    IWbemDecoupledBasicEventProvider *myEvtRegistrar;
    
    // -- Create an instance of IWbemDecoupledEventProvider
    hr = CoCreateInstance(CLSID_WbemDecoupledBasicEventProvider,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_IWbemDecoupledBasicEventProvider,
                          (void**)&myEvtRegistrar);
    
    if (SUCCEEDED(hr))
    {
       // -- Register the DecoupledEventProvider
       hr = myEvtRegistrar->Register(0,
                                     NULL,
                                     NULL,
                                     L"root\\cimv2",
                                     L"DecoupledEventProvider",
                                     NULL, NULL);
       if (SUCCEEDED(hr))
       {
          IWbemServices *pService = NULL;
          hr = myEvtRegistrar->GetService (0, NULL, &pService);
          if (SUCCEEDED(hr))
          {
             IWbemObjectSink *pSink = NULL;
             hr = myEvtRegistrar->GetSink ( 0, NULL, &pSink );
             if (SUCCEEDED(hr))
             {
                // Provide events
             }
          }
       } 
    }
    
  5. プロバイダーの機能に必要な WMI の呼び出しを行います。 詳細については、「クラスとインスタンスの情報の操作」を参照してください。 プロバイダーがスクリプトまたはアプリケーションからのデータ要求を処理する場合の詳細については、「クライアントの偽装」を参照してください。

終了する直前に、アプリケーションはそれ自体のクリーンアップ処理を行う必要があります。 以下の手順では、WMI が情報のクエリを実行しないように、分離プロバイダーの登録を解除する方法について説明します。

分離プロバイダーの登録を解除する方法を次の手順で説明します。

分離プロバイダーの登録を解除するには

  1. レジストラーの登録を解除して解放します。

    次のコード例は、レジストラーの登録を解除して解放する方法を示しています。

    myRegistrar->UnRegister();
    myRegistrar->Release();
    
  2. イベント プロバイダーの登録を解除して解放します。

    次のコード例は、イベント プロバイダーの登録を解除して解放する方法を示しています。

    myEvtRegistrar->UnRegister();
    myEvtRegistrar->Release();
    
  3. COM サーバーをクリーンアップします。

    COM ライブラリを初期化前の状態に戻す方法を次のコード例に示します。

    CoUninitialize();
    

名前空間セキュリティ記述子の設定

プロバイダーのセキュリティ保護

WMI プロバイダーの開発