在應用程式中納入提供者

建立要檢測的應用程式時,最佳做法是將提供者納入為應用程式本身內的元件。 此做法允許Windows Management Instrumentation (WMI) 直接與服務提供者互動,而不是間接透過程式 API 進行互動。 將提供者與 WMI 分離也會讓應用程式控制提供者生命週期,而不是 WMI。 如需撰寫在 WMI 進程中執行的提供者的詳細資訊,請參閱 撰寫提供者將資料提供給 WMI。 如需提供者裝載模型和安全性設定的詳細資訊,請參閱 提供者裝載和安全性

下圖說明 WMI、分離提供者和應用程式之間的關聯性。

relationship between wmi, decoupled provider, and application

如需分離提供者方法的詳細資訊,請參閱 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();
    

設定 Namepace 安全性描述項

保護您的提供者

開發 WMI 提供者