在應用程式中納入提供者

建立要檢測的應用程式時,最佳做法是將提供者納入為應用程式本身內的元件。 此做法允許 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();
    

設定 Namepace 安全性描述元

保護您的提供者

開發 WMI 提供者