WMI-обозреватель
Что такое WMI?
Windows Management Instrumentation (WMI) в дословном переводе — это инструментарий управления Windows. Если говорить более развернуто, то WMI — это одна из базовых технологий для централизованного управления и слежения за работой различных частей компьютерной инфраструктуры под управлением платформы Windows. Звучит страшно, а на самом деле это достаточно богатый набор инструментов, основные функции которого:
- Получать данные о системах (диски, процессоры, процессы, журналы событий и многое-другое)
- Выполнять широкий спектр административные задачи: от завершения процесса, до управления DHCP и DNS
- Создавать скрипты, срабатывающие при наступлении каких-либо событий в системе
- Получать данные счетчиков производительности
В WMI есть иерархическая адресация всех ресурсов — что-нибудь типа WinMgmts:{impersonationLevel=impersonate}!//myServer/root/cimv2:Win32_LogicalDisk)
, но вместе с иерархическим доступом к ресурсам есть и SQL-подобный язык получения данных. Этот язык обычно называется WQL и в сети есть множество примеров его использования. На инфостарте можно обратить внимание на следующие статьи:
- 1С:Системный Администратор 2.6 (WSH&WMI)
- 1С и Windows Script Host (WSH) и Windows Management Instrumentation (WMI). ОТ ТЕОРИИ К ПРАКТИКЕ. Часть I
- 1С и Windows Script Host (WSH) и Windows Management Instrumentation (WMI). ОТ ТЕОРИИ К ПРАКТИКЕ. Часть II
- 1С и Windows Script Host (WSH) и Windows Management Instrumentation (WMI). ОТ ТЕОРИИ К ПРАКТИКЕ. Часть III
В MSDN можно ознакомиться начиная со следующих статей:
- Windows Management Instrumentation, корневая страница справки
- WQL (SQL for WMI), страница описания языка запросов, он немного отличается от SQL
- Creating WMI Clients, документация по созданию приложений, использующих WMI
- Management Infrastructure Classes, важная часть справки, описание классов WMI, особенно Win32 Classes
Типичный запрос WQL выглядит так:
SELECT CommandLine, Handle, Name FROM Win32_Process
Результатом этого запроса будет табличка, начинающаяся примерно так:
CommandLine | Handle | Name |
0 | System Idle Process | |
4 | System | |
224 | smss.exe | |
320 | csrss.exe | |
372 | csrss.exe | |
380 | wininit.exe | |
412 | winlogon.exe | |
476 | services.exe | |
484 | lsass.exe | |
492 | lsm.exe | |
588 | svchost.exe | |
656 | svchost.exe | |
744 | svchost.exe | |
792 | svchost.exe | |
840 | svchost.exe | |
880 | svchost.exe | |
920 | svchost.exe | |
508 | svchost.exe | |
1096 | spoolsv.exe | |
1156 | hasplms.exe | |
1236 | svchost.exe | |
1316 | vmtoolsd.exe | |
1680 | TPAutoConnSvc.exe | |
1900 | dllhost.exe | |
1980 | msdtc.exe | |
taskhost.exe | 1724 | taskhost.exe |
TPAutoConnect.exe -q -i vmware -a COM1 -F 30 | 616 | TPAutoConnect.exe |
Зачем нужен WMI-обозреватель?
WMI документирована хорошо, но отлаживать WQL запросы непосредственно в 1С не было возможности, а пользоваться внешними утилитами ради пары строк запроса вовсе не хочется. Для этой цели я сделал простенький WMI-обозреватель.
Пользовательский интерфейс WMI-обозревателя
Интерфейс состоит из 2 закладок: Запрос и Настройки. На закладке Запрос есть только поле для ввода запроса. По умолчанию запрос выполняется на текущем ПК в файловой версии и на сервере предприятия (от имени rphost) в клиент-серверной версии. По кнопке «Выполнить запрос» появляется таблица с результатами.
Если настройки по умолчанию не устраивают, переходим на вторую закладку. Там можно настроить:
- Имя сервера с которого снимаются данные
- Если установлен флажок «Собирать системные свойства», то в таблице будут выданы внутренние свойства каждой записи. Обычно это не требуется.
- Если установлен флажок «Получать путь», то в таблице будут выдана колонка с иерархическим путём записи. Имеет смысл, если этот путь нужен для отладки запроса.
- Если установлен флажок «Собирать методы», то в таблице первой колонкой будет поле «Methods». Если два раза кликнуть мышкой или нажать Enter на этой колонке, то будет выдан табличный документ с методами, которые можно применять в программном коде к значению WMI данной строки
Картинки:
Как можно использовать WMI-обозреватель?
Здесь я приведу просто набор запросов и пояснение, что можно получить этим запросом. Проверяйте, экспериментируйте.
Запрос | Пояснение |
SELECT Handle, Name, VirtualSize FROM Win32_Process WHERE VirtualSize>100000000 AND CreationDate > «20130604000000.000000+420» | Выводится ID процесса, название процесса, размер адресуемого пространства для процессов, созданных позднее 4 июня 2013 года (в моём часовом поясе) |
SELECT * FROM Win32_Service WHERE PathName LIKE «%ragent%» | Все службы 1С со всеми данными по ним |
SELECT Name, Capacity, FreeSpace FROM Win32_Volume | Диски, их размер и свободное место |
SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor | Текущая загрузка процессора |
SELECT PercentDiskTime, AvgDiskQueueLength, DiskReadBytesPerSec, DiskWriteBytesPerSec FROM Win32_PerfFormattedData_PerfDisk_PhysicalDisk | Текущая загрузка диска |
Select * From meta_class | Выполняется долго, содержит очень много колонок! Выводит все классы WMI |
Как устроен WMI-обозреватель?
Весь WMI обозреватель благополучно поместился в одну управляемую форму (прямо скажу — не сильно сложную). Если по каким-то причинам Вы не можете скачать решение, то программный код этой формы приведен ниже.
&НаКлиенте
Процедура РезультатЗапросаВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
// При двойном клике на медоды, выводим их в табличный документ
Если Поле.Имя = «РезультатЗапросаMethods» Тогда
Методы = Элемент.ТекущиеДанные.Methods;
Если Методы.Количество()>0 Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
СчСтрок = 1;
Для каждого Метод Из Методы Цикл
ТабличныйДокумент.Область(СчСтрок, 1, СчСтрок, 1).Текст = Метод;
СчСтрок = СчСтрок + 1;
КонецЦикла;
ТабличныйДокумент.Показать();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьЗапрос(Команда)
ВыполнитьЗапросНаСервере();
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Серверные методы формы
&НаСервере
Процедура ВыполнитьЗапросНаСервере()
WMIЗапрос = ПолучитьCOMОбъектWMI(Объект.ИмяСервера);
// «*» желательно заменить для ускорения на конкретный список полей
WMIРезультаты = WMIЗапрос.ExecQuery(Объект.ТекстЗапроса);
РезультатЗапроса = ПреобразоватьРезультатыWMIвТаблицуЗначений(WMIРезультаты,
Объект.СобиратьСистемныеСвойства,
Объект.СобиратьМетоды,
Объект.ПолучатьПуть,
Ложь);
//РезультатЗапроса.Колонки.Удалить(«Значение»); // В ней содержатся «COMОбъект», которые не выводятся
ВывестиТаблицуЗначений(«РезультатЗапроса», РезультатЗапроса);
КонецПроцедуры
// Перезаполняет реквизит формы из таблицы значений.
// Предполагается, что реквизит уже есть на форме. Перезаполнение происходит
// полностью вместе с пересозданием колонок. Так медленнее, зато проще.
//
// Параметры:
// ИмяРеквизита — Строка — Имя заполняемого реквизита формы
// ЗначениеРеквизита — ТаблицаЗначений — чем заполнять реквизит
//
&НаСервере
Процедура ВывестиТаблицуЗначений(ИмяРеквизита, ЗначениеРеквизита)
ЭлементФормы = Элементы[ИмяРеквизита];
ПутьКДанным = ЭлементФормы.ПутьКДанным;
МассивДобавляемыхРеквизитов = Новый Массив;
МассивУдаляемыхРеквизитов = Новый Массив;
Для каждого ТекРеквизит из ПолучитьРеквизиты(ПутьКДанным) Цикл
МассивУдаляемыхРеквизитов.Добавить(ТекРеквизит.Путь + «.» + ТекРеквизит.Имя);
ИмяЭлементаВТаблице = ИмяРеквизита + ТекРеквизит.Имя;
Элемент = Элементы.Найти(ИмяЭлементаВТаблице);
Если не Элемент = Неопределено Тогда
Элементы.Удалить(Элемент);
КонецЕсли;
КонецЦикла;
Для Каждого Колонка Из ЗначениеРеквизита.Колонки Цикл
ДобавляемыйРеквизит = Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ПутьКДанным, Колонка.Имя);
МассивДобавляемыхРеквизитов.Добавить(ДобавляемыйРеквизит);
КонецЦикла;
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов,МассивУдаляемыхРеквизитов);
ЗначениеВРеквизитФормы(ЗначениеРеквизита, ПутьКДанным);
Для Каждого ТекРеквизит Из МассивДобавляемыхРеквизитов Цикл
ИмяЭлементаВТаблице = ИмяРеквизита + ТекРеквизит.Имя;
Элемент = Элементы.Добавить(ИмяЭлементаВТаблице, Тип(«ПолеФормы»), ЭлементФормы);
Элемент.Вид = ВидПоляФормы.ПолеВвода;
Элемент.ПутьКДанным = ПутьКДанным + «.» + ТекРеквизит.Имя;
Элемент.ТолькоПросмотр = Истина;
КонецЦикла;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Блок функций WMI, если хотите использовать их в своих программах, то лучше
// вынести в отдельный модуль. Модуль лучше сделать серверным, потому что
// используются таблицы значений. Не забудьте удалить директивы компиляции.
// Возвращает настроенный COM-объект WMI
//
// Параметры:
// ИмяСервера — Строка, имя или IP-адрес компьютера с которого будут получаться
// значения счетчиков производительности. Можно не указывать, если
// значения получаются со своего компьютера
// ИмяСервераИсполнителя — Строка, имя или IP-адрес компьютера на котором создаётся
// COM объект. Обычно можно не указывать
// ТочкаПодключения — Строка — по умолчанию «rootcimv2», но можно указать и своё
//
// Возвращаемое значение:
// COMОбъект — objWMIService
//
&НаСервереБезКонтекста
Функция ПолучитьCOMОбъектWMI(Знач ИмяСервера = Неопределено, Знач ИмяСервераИсполнителя = Неопределено, Знач ТочкаПодключения = Неопределено) Экспорт
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa389763(v=vs.85).aspx
Если Не ЗначениеЗаполнено(ИмяСервераИсполнителя) Тогда
Locator = Новый COMОбъект(«WbemScripting.SWbemLocator»);
Иначе
Locator = Новый COMОбъект(«WbemScripting.SWbemLocator», ИмяСервераИсполнителя);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ИмяСервера = «.»;
КонецЕсли;
Если Не ЗначениеЗаполнено(ТочкаПодключения) Тогда
ТочкаПодключения = «rootcimv2»;
КонецЕсли;
objWMIService = Locator.ConnectServer(ИмяСервера, ТочкаПодключения);
Возврат objWMIService;
КонецФункции
// Преобразует результаты WMI-запроса в таблицу значений
//
// Параметры:
// РезультатыWMI — COMОбъект — «сырые» результаты WMI-запроса
// СобиратьСистемныеСвойства — Булево — признак необходимости сбора системных свойств, необязательный, по умолчанию Ложь
// СобиратьМетоды — Булево — признак необходимости доступных методов, необязательный, по умолчанию Ложь
// ПолучатьПуть — Булево — получать или не получать колонку с полным путем к значению в терминах WMI, по умолчанию Истина.
// ПолучатьЗначениеWMI — Булево — получать или не получать колонку с самим значением WMI строки, по умолчанию Истина
//
// Возвращаемое значение:
// ТаблицаЗначений — Преобразованная таблица значений (нетипизированная, потому что добывать типы сложно)
//
// Примечание:
// 1. ПолучатьЗначение следует устанавливать в Ложь, если планируется вывод на форму (COM-объект,
// содержащийся в колонке нормально не выводится), в Истина, если планируется вызов методов или другая доп. логика
// 2. ПолучатьПуть можно установить в Ложь, если нужно минимизировать передачу данных
&НаСервереБезКонтекста
Функция ПреобразоватьРезультатыWMIвТаблицуЗначений(РезультатыWMI,
Знач СобиратьСистемныеСвойства = Ложь,
Знач СобиратьМетоды = Ложь,
Знач ПолучатьПуть = Истина,
Знач ПолучатьЗначениеWMI = Истина) Экспорт
ТаблицаWMI = Новый ТаблицаЗначений;
Если ПолучатьЗначениеWMI Тогда
ТаблицаWMI.Колонки.Добавить(«Значение»);
КонецЕсли;
Если ПолучатьПуть Тогда
ТаблицаWMI.Колонки.Добавить(«Path»);
КонецЕсли;
Если СобиратьМетоды Тогда
ТаблицаWMI.Колонки.Добавить(«Methods»);
КонецЕсли;
Для Каждого ЗначениеWMI Из РезультатыWMI Цикл
СтрокаТаблицыWMI = ТаблицаWMI.Добавить();
Если ПолучатьЗначениеWMI Тогда
СтрокаТаблицыWMI.Значение = ЗначениеWMI;
КонецЕсли;
Свойства = ПолучитьСтруктуруИзЗначенияWMI(ЗначениеWMI.Properties_);
ДобавитьСтруктуруВСтрокуТаблицаЗначений(СтрокаТаблицыWMI, Свойства);
Если СобиратьСистемныеСвойства Тогда
СистемныеСвойства = ПолучитьСтруктуруИзЗначенияWMI(ЗначениеWMI.SystemProperties_);
ДобавитьСтруктуруВСтрокуТаблицаЗначений(СтрокаТаблицыWMI, СистемныеСвойства);
КонецЕсли;
Если ПолучатьПуть Тогда
СтрокаТаблицыWMI.Path = ЗначениеWMI.Path_.Path;
КонецЕсли;
Если СобиратьМетоды Тогда
СтрокаТаблицыWMI.Methods = Новый Массив;
// Описания методов возвращаем для людей, поэтому описание «человеколюбивое»
Для Каждого МетодWMI из ЗначениеWMI.Methods_ Цикл
ОписаниеМетода = «Метод: » + МетодWMI.Name;
Если МетодWMI.InParameters <> Неопределено Тогда
Для Каждого ПараметрWMI из МетодWMI.InParameters.Properties_ Цикл
КвалификаторыПраметра = ПолучитьСтруктуруИзЗначенияWMI(ПараметрWMI.Qualifiers_);
ОписаниеМетода = ОписаниеМетода + Символы.ПС + «Входной параметр: » + ПараметрWMI.Name;
КонецЦикла;
КонецЕсли;
Если МетодWMI.OutParameters <> Неопределено Тогда
Для Каждого ПараметрWMI из МетодWMI.OutParameters.Properties_ Цикл
КвалификаторыПраметра = ПолучитьСтруктуруИзЗначенияWMI(ПараметрWMI.Qualifiers_);
ОписаниеМетода = ОписаниеМетода + Символы.ПС + «Выходной параметр: » + ПараметрWMI.Name;
КонецЦикла;
КонецЕсли;
СтрокаТаблицыWMI.Methods.Добавить(ОписаниеМетода);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаWMI;
КонецФункции
// Преобразует строку результатов WMI в структуру
//
// Параметры:
// ЗначениеWMI — COMОбъект — строка результатов WMI-запроса
//
// Возвращаемое значение:
// Структура — Коллекция значнний строки результатов WMI-запроса
//
&НаСервереБезКонтекста
Функция ПолучитьСтруктуруИзЗначенияWMI(ЗначениеWMI)
Рез = Новый Структура;
Для каждого СвойствоWMI из ЗначениеWMI Цикл
Если ТипЗнч(СвойствоWMI.Value) = Тип(«COMSafeArray») Тогда
Рез.Вставить(СвойствоWMI.Name, СвойствоWMI.Value.Выгрузить());// возможно массив надо будет переделать
Иначе
Рез.Вставить(СвойствоWMI.Name, СвойствоWMI.Value);
КонецЕсли
КонецЦикла;
Возврат Рез;
КонецФункции
// Добавляет все значения структуры в строку ТЗ. Если не хватает колонок — добавляет нетипизированную
//
// Параметры:
// ТекущаяСтрокаТаблицы — СтрокаТаблицыЗначений — Строка в которую записываются данные
// ДобавляемаяСтруктура — Структура — структура с значениями
//
// Возвращаемое значение:
// Структура — Коллекция значнний строки результатов WMI-запроса
//
&НаСервереБезКонтекста
Процедура ДобавитьСтруктуруВСтрокуТаблицаЗначений(ТекущаяСтрокаТаблицы, ДобавляемаяСтруктура)
ТаблицаЗначений = ТекущаяСтрокаТаблицы.Владелец();
Колонки = ТаблицаЗначений.Колонки;
Для Каждого ЭлементСтруктуры Из ДобавляемаяСтруктура Цикл
Если Неопределено = Колонки.Найти(ЭлементСтруктуры.Ключ) Тогда
Колонки.Добавить(ЭлементСтруктуры.Ключ);
КонецЕсли;
ТекущаяСтрокаТаблицы[ЭлементСтруктуры.Ключ] = ЭлементСтруктуры.Значение;
КонецЦикла
КонецПроцедуры
Напоследок
- Это не супер-пупер инструмент, а скорее наколеночная демонстрация работы с WMI, просто, к сожалению, я не нашёл аналога в существующих разработках.
- Проверено в 1С 8.2 и 1С 8.3 в управляемых формах.
- Очевидно, что при правильно настроенном rphost могут возникнуть проблемы с правами (rphost должен быть почти бесправен).
- Код этой обработки можете свободно использовать в своих разработках.
- Замечания и предложения принимаются 🙂
Поддержка WQL (WMI) реализована в консоли запросов (ИР) с конструктором запроса и отображением справочной информации по классам/свойствам.https://www.youtube.com/watch?v=bFDDJqToPTM
(1) tormozit, Я очень рад, что эта возможность появилась в ИР. Всем заинтересованным рекомендую для ознакомления/использования
Из пожеланий: явно нужен обычный режим, не все работают в УФ.
(3) Ну так, вон, Сергей утянул в свои тулзы, они не в УФ. Я дальше и не стал ничего делать, у Сергея всё отлично работает, меня устраивает.
Замечательная статья, но вопрос. Можно ли с помощью WMI повлиять на настройки принтера? Не на параметры страницы табличного документа, а именно на настройки принтера.
Необходимо: выводить документ с настройками:
2 копии
разобрать на копии = Истина
2 страницы на лист (страницы — портрет, лист — ландшафт)
двусторонняя печать
Сложность в том, что когда задаешь параметры для ТабДок средствами 1С, то упорно получается: (страницы — портрет, лист — портрет) или (страницы — ландшафт, лист — портрет), т.е. лист всегда портрет.
А если устанавливать параметры через настройки принтера, то все получается как надо.
Добрый день!
Тема весьма актуальная.
Было бы еще замечательно добавить дерево запросов, с возможностью сохранения в файл (по аналогии с консолью запросов).
П.С. никто не в курсе какой запрос нужен для получения сеансов пользователей — нужны логины (пытаюсь учитывать перекуры за день)?
С уважением
(6) А (1) Чем не устраивает?
(7) Прокси-сервер отказывается принимать соединения —https://www.youtube.com/watch?v=bFDDJqToPTM
(8) А в (0) он соглашается принимать соединения?
(8) Если возникла проблема с этим инструментом то рекомендую описать ее подробно на форуме основного сайта ИР.
(9) Да
(10) Дело не в инструменте (а в ссылке на него, слово ИР для меня не знакомо). Ютюб на работе закрыт. Попробовал поиском найти «инструмент разработчика» так в публикации нет упоминатий в описании об работе с WMI. И сюда то я пришел по этому же поиску «WMI» с яндекса (правьте и к вам придут с яндекса).