Saturday, July 16, 2011

USB device insert/remove monitoring with VBScript

Some time ago I got an Android Phone. To manage it from PC I installed MyPhoneExplorer. 
Thats great software but it doesn't have one vital feature: reconnect automatically when phone is connected via USB. On other hand it have such an option as "Connect on start".
So my idea was to write some program/script to kill MyPhoneExplorer's process on disconnect and start it on connect.
This script just sitting and watching when "Android ADB Interface" device get connected or disconnected via USB executing corresponding action on each event.

Const DEVICENAME = "Android ADB Interface"
Const EXENAME = "MyPhoneExplorer.exe"
Dim lastOperation
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}\\.\root\cimv2")

'Exit if already running
If alreadyRunning() Then: WScript.Quit

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

'Set event hook
objWMIService.ExecNotificationQueryAsync objSink, "Select * from __InstanceOperationEvent within 1 where TargetInstance ISA 'Win32_PnPEntity'"

'Get device IDs by name
EnumerateDevices DEVICENAME
objShell.Popup "USB monitoring started",2
'Infinite loop
Do
 WScript.Sleep 1000
Loop

'USB insert/remove hook procedure
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   


No comments:

Post a Comment