Один из неприятных аспектов диагностики проблем инструментария управления Windows (WMI) — сложность поиска двоичных файлов, отвечающих за поддержку огромного числа классов, зарегистрированных в системе. Каждый класс WMI имеет провайдера WMI, обычно представляющего COM-объект, как правило, в форме двоичного файла DLL. Поскольку провайдеры WMI представляют собой COM-объекты, основная задача заключается в нахождении идентификатора GUID, под которым зарегистрирован двоичный файл, после чего можно выполнять поиск в реестре этого GUID.

Типична проблема WMI — высокая загрузка процессора. У вас, вероятно, возникала проблема пиковой загрузки процессора, создаваемой процессом WMIPrvse.exe, и вы, возможно, даже знали, какой запрос WMI генерировал столь интенсивную деятельность процессора. Но как найти двоичный файл DLL, отвечающий за класс, к которому осуществляется запрос? И почему так важны сведения о DLL? Знание имени и местоположения DLL дает информацию о производителе, которому принадлежит данный двоичный файл, что позволяет выяснить, имеются ли для него обновления, и не является ли ваша проблема известным случаем, для которого уже предусмотрено исправление. Простой поиск в Интернете по контексту high cpu wmiprvse.exe («высокая загрузка процессора из-за процесса wmiprvse.exe») может дать слишком много ответов, ни один из которых не будет иметь отношения к делу. Однако если в контекст поиска включить точное имя DLL, например high cpu wmiprvse provider.dll, то вы, скорее всего, получите более точную и полезную информацию. Рассмотрим на примере, как найти двоичный файл DLL для класса WMI.

Включение протоколирования для поиска пространства имен класса

Первый шаг на пути поиска DLL конкретного класса состоит в выяснении, какому пространству имен принадлежит данный класс. Для этого необходимо включить протоколирование в журнал. Это делается следующим образом.

Для Windows Server 2003 и Windows XP. Включить запись подробных сведений в журнал можно с помощью элемента управления WMI под названием WMIMgmt.msc. Откройте вкладку Logging («Ведение журнала») этого элемента управления, затем щелкните переключатель Verbose («Подробно»). Это позволит увидеть записи в файле Wbemcore.log, подобные тем, что приведены на экране 1, с указанием на пространство имен, к которому осуществляются запросы.

connectionlogin: NtlMlogin —
   wszNetworkresource = root\cimv2

Для Windows Vista и Windows Server 2008. В Windows Vista и Server 2008 реализован новый механизм, предусматривающий ведение аналитического журнала Analytic log и журнала отладки Debug log. Эти журналы замещают реализованный ранее в Windows 2003 и XP журнал подробных сведений. Детальное описание шагов по включению ведения аналитического журнала и журнала отладки WMI в Windows Vista и более поздних версиях дано в записи блога группы Windows Management Infrastructure «Is WMIprvse a real villain?» (blogs.msdn.com/wmi/archive/2009/05/27/is-wmiprvse-a-real-villain.aspx).

Для тестирования я создал класс WMI под названием InstProvSamp. С экрана 1 нам нужно запомнить событие, регистрирующее запрос WMI к классу (select*from InstProvSamp), и пространство имен, которому принадлежит этот класс (\\root\default).

Экран 1. Журнал WMI

Поиск провайдера DLL

Зная класс WMI и пространство имен, можно приступить к поиску DLL-провайдера. Каждый класс WMI имеет квалификатор, называемый провайдером и носящий имя провайдера, которое совсем не обязательно соответствует имени двоичного файла. Необходимо выяснить имя квалификатора для нашего класса (InstprovSamp), для чего воспользуемся wbemtest.exe.

Запускаем wbemtest.exe, подключаемся к root\default и нажимаем кнопку Open Class («Открыть класс»). Вводим имя класса (в нашем примере это InstProvSamp). После нажатия OK открывается редактор объектов для данного класса. Как показано на экране 2, в разделе Qualifiers («Квалификаторы») есть строка provider («провайдер»), где указано имя InstProvSamp. В данном случае имя провайдера соответствует имени класса, однако обычно это не так.

Экран 2. Редактор объектов для InstProvSamp

Теперь необходимо по имени провайдера узнать идентификатор класса или CLSID провайдера. Для этого выполним запрос WMI для системного класса __Win32 Provider, который будет содержать идентификатор CLSID или GUID COM-объекта провайдера. Запускаем wbemtest.exe, подключаемся к целевому пространству имен (root\default), нажимаем кнопку Query (Запрос) и вводим следующий запрос:

select * from __Win32 provider where
   name="InstProvSamp"

Окно ответа будет содержать примерно такую запись:

_Win32 provider.Name="

Двойным щелчком на этой записи откроем «Редактор объекта» (см. экран 3).

Экран 3. Редактор объектов для провайдера реестра

В результате получим запись CLSID, указывающую нужный идентификатор GUID; каждый COM-объект помещает регистрационную запись в HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID. Можно воспользоваться regedit.exe, чтобы точно ориентировать поиск на регистрационную информацию COM и добраться непосредственно до имени и местоположения двоичного файла провайдера WMI, как показано на экране 4.

Экран 4. Регистрационная информация CLSID

Как уже говорилось, имя двоичного файла провайдера не всегда соответствует имени класса. Например, выяснилось, что провайдер реестра относится к классу root\default и носит имя RegProv. Однако фактическое имя DLL — STDPROV. DLL с местоположением в каталоге c:\windows\system32\wbem.

Другие варианты применения

Существуют различные ситуации, когда необходимо найти имя двоичного файла для данного класса WMI; диагностика проблемы высокой загрузки процессора — лишь один из множества возможных сценариев. Однако для любого из них описанные выше действия позволят установить имя двоичного файла и местоположение провайдера WMI.

Майкл Моралес (morales@microsoft.com) — старший инженер службы поддержки Microsoft Global Escalation Services. Специализируется на проблемах отладки и производительности Windows