1

Тема: VBScript: отслеживание событий таймера WMI

Пример создаёт таймер с интервалом 2 секунды, а затем отслеживает этот таймер в течение 20 секунд с выдачей соответствующих сообщений.

Option Explicit

Dim objSWbemServices
Dim objSWbemObjectIntervalTimerInstruction
Dim objSWbemObjectIntervalTimerInstructionInstance
Dim objSWbemSink

Dim strComputer


strComputer = "."

' Получаем объект SWbemServices
Set objSWbemServices = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

' Получаем класс __IntervalTimerInstruction
Set objSWbemObjectIntervalTimerInstruction = objSWbemServices.Get("__IntervalTimerInstruction")

' Создаём экземпляр класса __IntervalTimerInstruction
Set objSWbemObjectIntervalTimerInstructionInstance = objSWbemObjectIntervalTimerInstruction.SpawnInstance_

With objSWbemObjectIntervalTimerInstructionInstance
    ' Задаём значения созданного экземпляра…
    .IntervalBetweenEvents = 2000
    .TimerId = "MyTimer"
    
    ' и записываем его
    .Put_
End With

' Создаём объект SWbemSink
Set objSWbemSink = WScript.CreateObject("WbemScripting.SWbemSink", "SWbemSink_")

' Подписываемся асихронное оповещение о событиях 
objSWbemServices.ExecNotificationQueryAsync objSWbemSink, "SELECT * FROM __TimerEvent WHERE TimerID = 'MyTimer'"

' Делаем паузу в исполнении скрипта на 20 секунд
WScript.Echo "Waiting for events in 20 seconds..."
WScript.Sleep 1000 * 20
WScript.Echo "Finishing script..."

' Отменяем подписку на оповещение о событиях
objSWbemSink.Cancel

' Удаляем созданный экземпляр класса __IntervalTimerInstruction
objSWbemObjectIntervalTimerInstructionInstance.Delete_

' Очищаем объекты
Set objSWbemSink = Nothing
Set objSWbemObjectIntervalTimerInstructionInstance = Nothing
Set objSWbemObjectIntervalTimerInstruction = Nothing
Set objSWbemServices = Nothing

WScript.Quit 0
'=============================================================================

'=============================================================================
Sub SWbemSink_OnObjectReady(objObject, objAsyncContext)
    WScript.Echo "[" & CStr(Time()) & "] : Timer event has occurred."
End Sub
'=============================================================================

Автор примера - alexii.

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

2

Re: VBScript: отслеживание событий таймера WMI

Интересно, что свойства созданного экземпляра класса __IntervalTimerInstruction можно менять в обработчике события SWbemSink_OnObjectReady, а значит, и менять интервал вызова самого обработчика:

Option Explicit

Dim objSWbemServices
Dim objSWbemObjectIntervalTimerInstruction
Dim objSWbemObjectIntervalTimerInstructionInstance
Dim objSWbemSink

Dim strComputer


strComputer = "."

' Получаем объект SWbemServices
Set objSWbemServices = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

' Получаем класс __IntervalTimerInstruction
Set objSWbemObjectIntervalTimerInstruction = objSWbemServices.Get("__IntervalTimerInstruction")

' Создаём экземпляр класса __IntervalTimerInstruction
Set objSWbemObjectIntervalTimerInstructionInstance = objSWbemObjectIntervalTimerInstruction.SpawnInstance_

With objSWbemObjectIntervalTimerInstructionInstance
    ' Задаём значения созданного экземпляра…
    .IntervalBetweenEvents = 1000
    .TimerId = "MyTimer"
    
    ' и записываем его
    .Put_
End With

' Создаём объект SWbemSink
Set objSWbemSink = WScript.CreateObject("WbemScripting.SWbemSink", "SWbemSink_")

' Подписываемся асихронное оповещение о событиях 
objSWbemServices.ExecNotificationQueryAsync objSWbemSink, "SELECT * FROM __TimerEvent WHERE TimerID = 'MyTimer'"

' Делаем паузу в исполнении скрипта на 30 секунд
WScript.Echo "Waiting for events in 30 seconds..."
WScript.Sleep 1000 * 30
WScript.Echo "Finishing script..."

' Отменяем подписку на оповещение о событиях
objSWbemSink.Cancel

' Удаляем созданный экземпляр класса __IntervalTimerInstruction
objSWbemObjectIntervalTimerInstructionInstance.Delete_

' Очищаем объекты
Set objSWbemSink = Nothing
Set objSWbemObjectIntervalTimerInstructionInstance = Nothing
Set objSWbemObjectIntervalTimerInstruction = Nothing
Set objSWbemServices = Nothing

WScript.Quit 0
'=============================================================================

'=============================================================================
Sub SWbemSink_OnObjectReady(objObject, objAsyncContext)
    With objSWbemObjectIntervalTimerInstructionInstance
        ' Меняем значение интервала
        .IntervalBetweenEvents = .IntervalBetweenEvents + 1000
        
        ' Записываем
        .Put_

        WScript.Echo "[" & CStr(Time()) & "] : Timer event has occurred. Event's interval is " & CStr(.IntervalBetweenEvents) & "."
    End With
End Sub
'=============================================================================

Автор примера - alexii.

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