Поделиться через


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

При создании приложения, которое необходимо инструментировать, рекомендуется включить поставщика в качестве компонента в самом приложении. Эта практика позволяет инструментарию управления 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