Включение поставщика в приложение

При создании приложения, которое должно быть инструментировано, рекомендуется включить поставщика в качестве компонента в само приложение. Это позволяет инструментарию управления Windows (WMI) взаимодействовать с поставщиком услуг напрямую, а не косвенно через ПРОГРАММНЫЙ API. Разделение поставщика от инструментария WMI также позволяет приложению управлять сроком существования поставщика, а не WMI. Дополнительные сведения о создании поставщика, который выполняется в процессе WMI, см. в разделе Передача данных в WMI путем написания поставщика. Дополнительные сведения о модели размещения и параметрах безопасности для поставщика см. в разделе Размещение и безопасность поставщика.

На следующей схеме показана связь между WMI, несвязанным поставщиком и приложением.

связь между WMI, несвязанным поставщиком и приложением

Дополнительные сведения о несвязанных методах поставщика см. в разделах IWbemDecoupledRegistrar и IWbemDecoupledBasicEventProvider.

Примечание

Несвязанный поставщик поддерживает экземпляр, метод, поставщиков событий и потребителей событий. Он не поддерживает поставщиков классов и свойств. Дополнительные сведения см. в разделах Написание поставщика классов и Запись поставщика свойств.

 

Для правильной компиляции примеров кода в этом разделе требуются следующие ссылки и инструкции #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