суббота, 16 июля 2011 г.

Мониторинг подключения/отключения USB устройств на VBScript

Некоторое время назад у меня завялся телефон на Android. Чтобы управлять им с компьютера я установил MyPhoneExplorer.
Это отличная программа, но все-же в ней не хватает одной важной для меня функции, а именно: автоматического переподключения при подключении телефона к USB. С другой стороны в ней есть такая опция, как "Подключаться при запуске".
Отсюда у меня появилась идея написать скриптик, который будет прибивать процесс MyPhoneExplorer при отключении телефона и запускать при подключении.
Наконец я оформил это на VBScript. Этот скрипт наблюдает за подключением/отключением устройства под названием "Android ADB Interface" и выполняет соответствующие действия:
Const DEVICENAME = "Android ADB Interface"
Const EXENAME = "MyPhoneExplorer.exe"
Dim lastOperation
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}\\.\root\cimv2")

'Выйти, если скрипт уже запущен
If alreadyRunning() Then: WScript.Quit

Set objSink = WScript.CreateObject("WBemScripting.SWbemSink","event_")
Set objShell = CreateObject("WScript.Shell")
Set deviceIDs = CreateObject("Scripting.Dictionary")

'Установим перехватчик событий
objWMIService.ExecNotificationQueryAsync objSink, "Select * from __InstanceOperationEvent within 1 where TargetInstance ISA 'Win32_PnPEntity'"

'Получим ID устройств по заданному имени
EnumerateDevices DEVICENAME
objShell.Popup "Мониторинг USB начат!",2
'Бесконечный цикл
Do
 WScript.Sleep 1000
Loop

'Перехватчик событий подключения/отключения USB устройств
Sub event_OnObjectReady( objEvent, objContext )
 With objEvent
  If deviceIDs.Exists(.TargetInstance.DeviceId) Then
   Select Case .Path_.Class
    Case "__InstanceCreationEvent"
     If lastOperation <> "Insert" Then
      lastOperation = "Insert"
      OnInsert
     End If
      
    Case "__InstanceDeletionEvent"
     If lastOperation <> "Remove" Then
      lastOperation = "Remove"
      OnRemove
     End If
    End Select
  End If
 End With
End Sub

Sub OnInsert
 objShell.Run EXENAME,1,0
End Sub

Sub OnRemove
 objShell.Run "taskkill /f /im " & EXENAME,0,0
End Sub

Sub EnumerateDevices(name)
 Set objDevices = objWMIService.ExecQuery("SELECT DeviceId FROM Win32_PnPSignedDriver WHERE Description='" & name & "'")
 For Each dev in objDevices
  deviceId = dev.DeviceId
  If Not deviceIDs.Exists(deviceId) Then
   deviceIDs.Add deviceId, deviceId
  End If
  d = d + 1
 Next
End Sub

Function alreadyRunning()
 alreadyRunning = False
 wscrCount = ProcessCount( "%wscript%" & WScript.ScriptName & "%" )
 cscrCount = ProcessCount( "%cscript%" & WScript.ScriptName & "%" )
 If  wscrCount > 1 or cscrCount > 1 Then:alreadyRunning = True
End Function

Public Function ProcessCount(likestr)
 Set colItems = objWMIService.ExecQuery("SELECT Name,CommandLine FROM Win32_Process WHERE CommandLine Like '" & likestr & "'")
 ProcessCount = colItems.Count
End Function   

VBS-файл можно скачать здесь

Комментариев нет:

Отправить комментарий