В одной из предыдущих статей я обещал рассказать о потребителях событий в мире WMI, да всё никак руки не доходили. Вот, исправляюсь.
Если вы не помните, что это такое – посмотрите по категории WMI статьи, они должны показаться вам интересными.
В развитии темы сообщаю, что получать информацию о классах WMI мы можем не только по запросу “спрашиваем – нам отвечают”, но и по какому-либо событию “что-то произошло – пришло сообщение”. На первый взгляд, ситуация обычная. Но если хорошенько задуматься, можно понять, какие возможности открывает перед нами эта возможность. Особенно это касается средств мониторинга.
Например, нам нужно отслеживать подключенные USB-устройства. Причем, отследить даже сам момент подключения. Нет ничего проще:
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery ("SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.DriveType = 2")
Wscript.Echo "Подключите USB флешку"
Do While(True)
Set objReceivedEvent = objEvents.NextEvent
Wscript.Echo "Объект: " & objReceivedEvent.TargetInstance.Caption
Wscript.Echo "Файловая система: " & objReceivedEvent.TargetInstance.FileSystem
Wscript.Echo "Описание: " & objReceivedEvent.TargetInstance.Description
Loop
Сохраняем данный скрипт в файле script.vbs, далее, запускаем скрипт через командную строку (если потребуется, указываем путь к файлу скрипта):
C:\>cscript script.vbs

Подключаем флешку и видим:

Давайте разберемся, что произошло.
- Подключаемся к репозиторию CIMv2 пространства имен
- Создаем временный потребитель событий в виде WQL (похож на SQL, правда?) запроса. __InstanceCreationEvent – срабатывает каждый раз, когда создается новый экземпляр класса. Win32_LogicalDisk – сам класс, который создается после подключения USB-устройства (на самом деле любого дискогового накопителя, но далее мы фильтруем DriveType)
- Как только подключена флешка, создается экземпляр класса Win32_LogicalDisk, и фиксируется событие об этом через метод ExecNotificationQuery. При этом, TargetInstance – ссылается на объект, вывзвавший событие, то есть на наш экземпляр класса (чтобы его не искать среди множества других).
- Просматривая объект событий, удовлетворяющих условию objEvents мы получаем необходимые нам поля – заголовок, файловую систему и т.д. Узнать полный список полей можно из репозитория или воспользоваться бесплатной утилиткой WMICodeCreator.
Вышеуказанный пример демонстрирует синхронную обработку событий. При такой обработке процесс ждёт наступления события, заданного в WQL и больше ничего не делает. То есть в бесконечном цикле проверяет, наступило какое-либо событие или не наступило. В случае, если наступило, вызывается метод NextEvent, который возвращает сценарию управление только если совершилось событие, которое мы описали.
Кроме синхронной есть и асинхронная обработка. Более гибкий метод, в котором для отслеживания регистрируется специальный подписчик, а скрипт может продолжать дальнейшее выполнение. Как только наступает нужное событие, выполнение скрипта прерывается и продолжается далее с этого же места, а управление передается на асинхронный обработчик.
Это весьма неплохой пример. Позднее я покажу, как можно регистрировать в системе постоянную подписку на определенные события. И тогда не будет необходимости держать окно выполнения скрипта открытым.
Comments: