Jump to content

How to activate a program when a specific usb device is connected


Recommended Posts

Hi everyone,

I have search the forum for a couple of hours without finding a clue to where to begin with my problem.

Here is what I want:

I want to be able to start a program when a SPECIFIC usb device is connected. I want it to work also regardless of the usb port. (I have a usb bluetooth dongle paired with a PS3 Controller. When I put it on from the controller, the dongle connects. It does the same thing as if I would have a usb plugged in the PC.)

What I would like it to be able to do is something like this:

If usb_id "0A56D777E" is connected Then

Run : '''whatever application'

Any help is appreciated. Maybe there is already something similar to what I want to achieve.

Thx

Dave

Link to comment
Share on other sites

Something like this: http://mattcollinge.wordpress.com/software/usb-detect-and-launch/ ?

Your usb device does not create/have a drive letter, right?

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

divadnivip007,

Here is one possible way to do this.

;
; check for a specific volume label every 1 second
;
local $DriveLabelToWatchFor = "Game_Shit"
while 1
 Local $aDrives = DriveGetDrive("ALL")
 If @error Then
  MsgBox(4096, "DriveGetDrive", "It appears an error occurred.")
 Else
  For $i = 1 To $aDrives[0]
   if drivegetlabel($aDrives[$i]) = $DriveLabelToWatchFor then
    ;
    ;   do whatever you want here
    ;
    consolewrite("Got IT on logical device = " & $aDrives[$i] & @lf)
   endif
  Next
 EndIf
 sleep(1000)
wend

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

file:///C:/Users/Mistgun/Desktop/New%20Bitmap%20Image.bmp

Thx guys for your fast response,

It works great with usb with a letter in windows ex. G\:, D:\.

What I want is to know when a USB bluetooth dongle is connected to the computer. The dongle is listed in the Device and Printers. (See image below).

I have tried with other functions like DriveGet"serials" but it dosent work. Is my USB bluetooth dongle a Drive? Maybe there is another function for this sort of dongle.

Here are the information that I can have (See the image for the complete list):

- Manufacturer ID

- Address ex : (00:11:67:d6:01:37)

- The location ex: Port_#0002.Hub_#0001

- The adapter MAC ex: 57.0a.3d.83.15.00

Posted Image

Posted Image

This is the complete list of what information i can obtain:

Posted Image

Link to comment
Share on other sites

For a start, see if this code detects insertion/removal of your device.

If not, maybe there is something in WMI, or you may have to poll with the device/setup API.

Use a WM_DEVICECHANGE message handler in your script to get USB port events - drives and devices (iPod, bluetooth, etc).

(someone once mentioned that WM_DEVICECHANGE apparently blocked new drive preparation if device registration (RegisterDeviceNotification) was not passed on to the system from the message handler?)

You'll need to look into the details of that.

Once you get an event from your device insertion, use the Device API to look for your device.

Note: all USB events will trigger this (and multiple times per event), but at least you won't have to poll with device api code every few seconds.

LaCastiglione posted a WM_DEVICECHANGE example with device registration.

Weaponx posted a Device/Setup API UDF.

#include <WindowsConstants.au3>
$Form1_1 = GUICreate("")
GUIRegisterMsg($WM_DEVICECHANGE, "WM_DEVICECHANGE")
GUISetState(@SW_SHOW)
Do
Until GUIGetMsg() = -3

Func WM_DEVICECHANGE($hWnd, $msg, $wParam, $lParam)
    #forceref $hWnd, $msg, $wParam, $lParam
    ;need to check with device api as there is no data to retrieve here for usb devices that are not drives.
    ;for an iPod insertion/removal there is no struct in lParam and wParam is always DBT_DEVNODES_CHANGED
    Local $DBT_DEVNODES_CHANGED = 0x00000007
    Switch $wParam
        Case $DBT_DEVNODES_CHANGED
            ConsoleWrite("+wParam: " & $wParam & @CRLF & "+lParam: "  & $lParam & @CRLF & @CRLF)
            ;run device api code
    EndSwitch
    Return 'GUI_RUNDEFMSG'
EndFunc ;==>WM_DEVICECHANGE

I see fascists...

Link to comment
Share on other sites

Thx unmutual,

Is your code supposed to tell if there is a device change? Do i have to change part of the code? Sorry but I'm a newbie.

I've run into another thread from someone. When I start my ps3 controller, and when I disconnect the controller, a GUI pops up and says "Token Removed ". I don't have a clue of

what it does but I think it can lead to the right direction. The code detects changes from any usb dongle.

Here is the code :

Global $Paused
HotKeySet("{Pause}","TogglePause")

$WM_DEVICE_CHANGE = 0x0219
$DBT_DEVNODES_CHANGED = "0x00000007"

GUICreate("")

GUIRegisterMsg($WM_DEVICE_CHANGE , "MyFunc")

Func MyFunc($hWndGUI, $MsgID, $WParam, $LParam)
If $WParam == $DBT_DEVNODES_CHANGED Then
If($PAUSED <> True)Then
tokenChk()
EndIf
EndIf
EndFunc

While 1
$GuiMsg = GUIGetMsg()
WEnd

Func TogglePause()
$Paused = NOT $Paused
While $Paused
sleep(100)
ToolTip('Script is "Paused"',0,0)
WEnd
ToolTip("")
EndFunc

Func tokenChk()

$mcount = 0

$strComputer = "."

$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
$colDevices = $objWMIService.ExecQuery ("Select * From Win32_USBControllerDevice")

For $objDevice in $colDevices
$strDeviceName = $objDevice.Dependent
$strQuotes = Chr(34)
$strDeviceName = StringReplace($strDeviceName, $strQuotes, "")
$arrDeviceNames = StringSplit($strDeviceName, "=")
$strDeviceName = $arrDeviceNames[2]
$colUSBDevices = $objWMIService.ExecQuery ("Select * From Win32_PnPEntity Where DeviceID = '" & $strDeviceName & "'")

For $objUSBDevice in $colUSBDevices
If($objUSBDevice.Description == "USB Token")Then
$mcount = 1
MsgBox(0,"USB Description",$objUSBDevice.Description)
MsgBox(0,$objUSBDevice.Description,$objUSBDevice.Manufacturer)
EndIf
Next
Next
If ($mcount<>1)Then
MsgBox(0,"Alert!","Token Removed")
EndIf
EndFunc
Link to comment
Share on other sites

The code you found will do what you want, it has the WMI code to enumerate connected USB devices.

You just need the description or some other property for your device.

Use the Test() function to get all of the properties of Win32_PnPEntity.

You are using the SciTE editor with its built in Console message window?

;_Test() ;use to find your USB device WMI property name for $sDeviceProperty and value for $sUSBDevice
;Exit

HotKeySet("{ESC}", "_Exit")

Global $sDeviceProperty = "Caption" ;Caption, Description, DeviceID, Name, PNPDeviceID
Global $sUSBDevice = "Apple iPod" ;property value for Caption, Description, DeviceID, Name or PNPDeviceID

Global $fDeviceActive = _FindUSBDevice($sDeviceProperty) ;initialize variable with device state. global var prevents retriggering by other device insertion/removal
If $fDeviceActive = -1 Then ConsoleWrite("! Error finding device: " & @error & @LF)

ConsoleWrite("> Monitoring - Press ESC to Exit: "  & @LF)

_Main()

Func _Main()
    Local Const $WM_DEVICE_CHANGE = 0x0219
    GUICreate("") ;dummy gui for receiving window messaging
    GUIRegisterMsg($WM_DEVICE_CHANGE, "_WM_DEVICE_CHANGE")
    While 1
        Sleep(1000)
    WEnd
EndFunc   ;==>_Main

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func _WM_DEVICE_CHANGE($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $wParam, $lParam
    Local Const $DBT_DEVNODES_CHANGED = 0x00000007
    If $wParam = $DBT_DEVNODES_CHANGED Then
        Switch _FindUSBDevice($sDeviceProperty)
            Case 1
                If Not $fDeviceActive Then ;check current state buffer to prevent events from other usb devices
                    $fDeviceActive = True
                    ConsoleWrite("+ Device Connected" & @LF)
                EndIf
            Case 0
                If $fDeviceActive Then ;check current state buffer to prevent events from other usb devices
                    $fDeviceActive = False
                    ConsoleWrite("! Device Disconnected" & @LF)
                EndIf
            Case -1
                ConsoleWrite("! WMI Error: " & @error & @LF)
        EndSwitch
    EndIf
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>_WM_DEVICE_CHANGE

Func _FindUSBDevice($sProperty = "*", $strComputer = ".")
    Local $objWMIService = ObjGet("winmgmts:" & $strComputer & "rootcimv2")
    If @error Then Return SetError(1, 0, -1)
    Local $colDevices = $objWMIService.ExecQuery("Select Dependent From Win32_USBControllerDevice") ;Select Dependent instead of Select *  - limit items in collection to speed up response slightly
    If Not IsObj($colDevices) Then Return SetError(2, 0, -1)
    Local $arrDeviceNames, $colUSBDevices
    For $objDevice In $colDevices
        $arrDeviceNames = StringSplit(StringReplace($objDevice.Dependent, Chr(34), ""), "=", 2)
        If @error Or UBound($arrDeviceNames) <> 2 Then Return SetError(3, 0, -1)
        $colUSBDevices = $objWMIService.ExecQuery("Select " & $sProperty & " From Win32_PnPEntity Where DeviceID = '" & $arrDeviceNames[1] & "'");Select $sProperty instead of Select * - limit items in collection to speed up response slightly
        If Not IsObj($colUSBDevices) Then Return SetError(4, 0, -1)
        For $objUSBDevice In $colUSBDevices
            ;ConsoleWrite("USB Description: " & Execute("$objUSBDevice." & $sProperty) & @LF)
            If (Execute("$objUSBDevice." & $sProperty) == $sUSBDevice) Then Return 1 ;device found
            If @error Then Return SetError(5, 0, -1)
        Next
    Next
    Return 0 ;device not found
EndFunc   ;==>_FindUSBDevice


Func _Test($strComputer = ".")
    ;use to find your USB device WMI property name  and value, then copy/paste value to $sUSBDevice and property name to $sDeviceProperty
    Local $objWMIService = ObjGet("winmgmts:" & $strComputer & "rootcimv2")
    Local $colDevices = $objWMIService.ExecQuery("Select Dependent From Win32_USBControllerDevice")
    Local $arrDeviceNames, $colUSBDevices, $Output

    For $objDevice In $colDevices
        $arrDeviceNames = StringSplit(StringReplace($objDevice.Dependent, Chr(34), ""), "=", 2)
        $colUSBDevices = $objWMIService.ExecQuery("Select * From Win32_PnPEntity Where DeviceID = '" & $arrDeviceNames[1] & "'")

        For $objItem In $colUSBDevices ;properties that usually return no value or are not needed are commented
            ;$Output &= "Availability: " & $objItem.Availability & @CRLF
            $Output &= "Caption: " & $objItem.Caption & @CRLF
            $Output &= "Description: " & $objItem.Description & @CRLF
            $Output &= "Name: " & $objItem.Name & @CRLF
            $Output &= "Manufacturer: " & $objItem.Manufacturer & @CRLF
            $Output &= "ClassGuid: " & $objItem.ClassGuid & @CRLF
            ;$Output &= "ConfigManagerErrorCode: " & $objItem.ConfigManagerErrorCode & @CRLF
            ;$Output &= "ConfigManagerUserConfig: " & $objItem.ConfigManagerUserConfig & @CRLF
            ;$Output &= "CreationClassName: " & $objItem.CreationClassName & @CRLF
            $Output &= "DeviceID: " & $objItem.DeviceID & @CRLF
            ;$Output &= "ErrorCleared: " & $objItem.ErrorCleared & @CRLF
            ;$Output &= "ErrorDescription: " & $objItem.ErrorDescription & @CRLF
            ;$Output &= "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF
            ;$Output &= "LastErrorCode: " & $objItem.LastErrorCode & @CRLF
            $Output &= "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF
            $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
            ;$Output &= "PowerManagementCapabilities: " & $strPowerManagementCapabilities & @CRLF
            ;$Output &= "PowerManagementSupported: " & $objItem.PowerManagementSupported & @CRLF
            $Output &= "Service: " & $objItem.Service & @CRLF
            $Output &= "Status: " & $objItem.Status & @CRLF
            ;$Output &= "StatusInfo: " & $objItem.StatusInfo & @CRLF
            ;$Output &= "SystemCreationClassName: " & $objItem.SystemCreationClassName & @CRLF
            ;$Output &= "SystemName: " & $objItem.SystemName & @CRLF
            ConsoleWrite("+ " & $Output & @LF) ;use to find your device name, then copy/paste to $sUSBDevice declaration
            $Output = ""
        Next
    Next
EndFunc   ;==>_Test
Edited by rover

I see fascists...

Link to comment
Share on other sites

A nice example rover, will add to my snippets folder.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Another quick question,

If I wanted to check if another usb device is connected or disconnected how would the code change.

I tried to make to of the same code but it didint worked.

Here is the same script but by adding a second usb device. I want to run a different program depending on the usb that is connected.

;Gamepad XBOX_360_DEVICE_00:00
HotKeySet("{ESC}", "_Exit")

Global $sDeviceProperty = "PNPDeviceID" ;Caption, Description, DeviceID, Name, PNPDeviceID
Global $sUSBDevice = "USB\VID_045E&PID_02A1&IG_00\6&366022B6&1&00" ;property value for Caption, Description, DeviceID, Name or PNPDeviceID. For PNPDeviceID : Find --> Device Instance Path.

Global $sUSBDevice = "USB\VID_045E&PID_02A1&IG_02\6&366022B6&1&02" ;second usb device




Global $fDeviceActive = _FindUSBDevice($sDeviceProperty) ;initialize variable with device state. global var prevents retriggering by other device insertion/removal
If $fDeviceActive = -1 Then ConsoleWrite("! Error finding device: " & @error & @LF)

ConsoleWrite("> Monitoring - Press ESC to Exit: " & @LF)

_Main()

Func _Main()
Local Const $WM_DEVICE_CHANGE = 0x0219
GUICreate("") ;dummy gui for receiving window messaging
GUIRegisterMsg($WM_DEVICE_CHANGE, "_WM_DEVICE_CHANGE")
While 1
Sleep(1000)
WEnd
EndFunc ;==>_Main

Func _Exit()
Exit
EndFunc ;==>_Exit

Func _WM_DEVICE_CHANGE($hWnd, $Msg, $wParam, $lParam)
#forceref $hWnd, $Msg, $wParam, $lParam
Local Const $DBT_DEVNODES_CHANGED = 0x00000007
If $wParam = $DBT_DEVNODES_CHANGED Then
Switch _FindUSBDevice($sDeviceProperty)
Case 1
If Not $fDeviceActive Then ;check current state buffer to prevent events from other usb devices
$fDeviceActive = True




Run("Whatever program") ; when 1 usb device is connected

Run("Whatever program") ; when 2 usb device is connected






EndIf
Case 0
If $fDeviceActive Then ;check current state buffer to prevent events from other usb devices
$fDeviceActive = False
ConsoleWrite("! Device Disconnected" & @LF)
EndIf
Case -1
ConsoleWrite("! WMI Error: " & @error & @LF)
EndSwitch
EndIf
Return "GUI_RUNDEFMSG"

EndFunc ;==>_WM_DEVICE_CHANGE

Func _FindUSBDevice($sProperty = "*", $strComputer = ".")
Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
If @error Then Return SetError(1, 0, -1)
Local $colDevices = $objWMIService.ExecQuery("Select Dependent From Win32_USBControllerDevice") ;Select Dependent instead of Select * - limit items in collection to speed up response slightly
If Not IsObj($colDevices) Then Return SetError(2, 0, -1)
Local $arrDeviceNames, $colUSBDevices
For $objDevice In $colDevices
$arrDeviceNames = StringSplit(StringReplace($objDevice.Dependent, Chr(34), ""), "=", 2)
If @error Or UBound($arrDeviceNames) <> 2 Then Return SetError(3, 0, -1)
$colUSBDevices = $objWMIService.ExecQuery("Select " & $sProperty & " From Win32_PnPEntity Where DeviceID = '" & $arrDeviceNames[1] & "'");Select $sProperty instead of Select * - limit items in collection to speed up response slightly
If Not IsObj($colUSBDevices) Then Return SetError(4, 0, -1)
For $objUSBDevice In $colUSBDevices
;ConsoleWrite("USB Description: " & Execute("$objUSBDevice." & $sProperty) & @LF)
If (Execute("$objUSBDevice." & $sProperty) == $sUSBDevice) Then Return 1 ;device found
If @error Then Return SetError(5, 0, -1)
Next
Next
Return 0 ;device not found
EndFunc ;==>_FindUSBDevice

Thx for your help

Dave

Link to comment
Share on other sites

It is advisable to get to the point and state what you are trying to do in your first post instead of trickling information and asking for more changes.

I tend to limit how much volunteer support I put into a forum thread and mostly post code not found on the forum or in the required form without modification/combining of forum examples.

I might as well finish this, as it seems with a bit of looking there are no examples on the forum coded for non-drive usb devices.

So here is a modified version that accommodates as many devices as needed and is faster.

A few changes were required to check for 2 or more devices.

These changes slowed down the code even more.

There are multiple device change events for each device insertion/removal, so there was an even longer time with high cpu use due to the many calls to _FindUSBDeviceEx()

A test with WMI Code Creator showed how fast the Win32_PnPEntity query is, so nesting the two WMI queries was the cause of the long high cpu use.

The Win32_USBControllerDevice query is not needed for finding USB devices.

This version is much faster and does not have the long high cpu usage time of the previous version.

Though there are still the short high cpu spikes on device insertion/removal

This topic can be considered solved.

Enjoy

;coded by rover 2k12
HotKeySet("{ESC}", "_Exit")


;Array with property, property value, state (always intialized to 0), state buffer (always intialized to False or 0), your command string
;Global $aUSBDevPropState[2][5] = [["Caption", "Apple iPod", 0, False, "Whatever program1"],["PNPDeviceID", "USBSTOR\DISK&VEN_SAMSUNG&PROD_ANDROID&REV_FFFF\T499F99F0CB8&0", 0, False, "Whatever program2"]]
Global $aUSBDevPropState[2][5] = [["PNPDeviceID", "USB\VID_045E&PID_02A1&IG_00\6&366022B6&1&00", 0, False, "Whatever program1"], ["PNPDeviceID", "USB\VID_045E&PID_02A1&IG_02\6&366022B6&1&02", 0, False, "Whatever program2"]]

_FindUSBDeviceEx($aUSBDevPropState, ".", 1) ;initialize array with device state. global var prevents retriggering by other device insertion/removal
If @error Then
ConsoleWrite("! Error finding device(s) : " & @error & @LF)
For $i = 0 To UBound($aUSBDevPropState) - 1
If $aUSBDevPropState[$i][2] = -1 Then ConsoleWrite("! Error finding device : " & $aUSBDevPropState[$i][0] & ": " & $aUSBDevPropState[$i][1] & @LF)
Next
Exit
EndIf

ConsoleWrite("> Monitoring - Press ESC to Exit: " & @LF & @LF)

_Main()

Func _Main()
Local Const $WM_DEVICECHANGE = 0x0219
GUICreate("") ;dummy gui for receiving window messaging
GUIRegisterMsg($WM_DEVICECHANGE, "_WM_DEVICECHANGE")
While 1
Sleep(1000)
WEnd
EndFunc ;==>_Main

Func _Exit()
Exit
EndFunc ;==>_Exit

Func _WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam)
#forceref $hWnd, $Msg, $wParam, $lParam
Local Const $DBT_DEVNODES_CHANGED = 0x00000007
If $wParam = $DBT_DEVNODES_CHANGED Then
Switch _FindUSBDeviceEx($aUSBDevPropState)
Case 1
For $i = 0 To UBound($aUSBDevPropState) - 1
If $aUSBDevPropState[$i][2] And Not $aUSBDevPropState[$i][3] Then ;check current state buffer to prevent events from other usb devices
$aUSBDevPropState[$i][3] = True
ConsoleWrite("+ Device Connected: " & $aUSBDevPropState[$i][0] & ": " & $aUSBDevPropState[$i][1] & @LF)
ConsoleWrite("- Run: " & $aUSBDevPropState[$i][4] & @LF & @LF)
;Run($aUSBDevPropState[$i][4])
EndIf
If Not $aUSBDevPropState[$i][2] And $aUSBDevPropState[$i][3] Then ;check current state buffer to prevent events from other usb devices
$aUSBDevPropState[$i][3] = False
ConsoleWrite("! Device Disconnected: " & $aUSBDevPropState[$i][0] & ": " & $aUSBDevPropState[$i][1] & @LF & @LF)
EndIf
Next
Case 0
For $i = 0 To UBound($aUSBDevPropState) - 1
If Not $aUSBDevPropState[$i][2] And $aUSBDevPropState[$i][3] Then ;check current state buffer to prevent events from other usb devices
$aUSBDevPropState[$i][3] = False
ConsoleWrite("! Device Disconnected: " & $aUSBDevPropState[$i][0] & ": " & $aUSBDevPropState[$i][1] & @LF & @LF)
EndIf
Next
Case -1
ConsoleWrite("! _FindUSBDeviceEx() WMI Error: " & @error & @LF)
EndSwitch
EndIf
Return "GUI_RUNDEFMSG"

EndFunc ;==>_WM_DEVICECHANGE

Func _FindUSBDeviceEx(ByRef $aUSBDevice, $strComputer = ".", $iInit = 0)
;rover 2k12
;with the Win32_USBControllerDevice code removed, this is much faster
If UBound($aUSBDevice, 0) <> 2 Or UBound($aUSBDevice, 2) <> 5 Then Return SetError(1, 0, -1) ;check user array for correct dimensions and column count
Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
If @error Then Return SetError(2, 0, -1)
Local $colUSBDevices, $iCnt = 0, $iSize = UBound($aUSBDevice) - 1, $sProperties

For $i = 0 To $iSize ;concatenate comma delimited properties
$sProperties &= $aUSBDevice[$i][0]
If $i <> $iSize And $iSize > 0 Then $sProperties &= ","
$aUSBDevice[$i][2] = 0 ;reset device state
Next

$colUSBDevices = $objWMIService.ExecQuery("Select " & $sProperties & " From Win32_PnPEntity");Select $sProperties instead of Select * - limit items in collection to speed up response slightly
If Not IsObj($colUSBDevices) Then Return SetError(3, 0, -1) ;error finding device

For $objUSBDevice In $colUSBDevices
For $iDev = 0 To $iSize
;ConsoleWrite("USB Description: " & Execute("$objUSBDevice." & $aUSBDevice[$iDev][0]) & @LF)
If (Execute("$objUSBDevice." & $aUSBDevice[$iDev][0]) == $aUSBDevice[$iDev][1]) Then
;ConsoleWrite("USB Description: " & Execute("$objUSBDevice." & $aUSBDevice[$iDev][0]) & @LF)
$iCnt += 1 ;increment found device count
$aUSBDevice[$iDev][2] = 1 ;device found
If $iInit Then $aUSBDevice[$iDev][3] = True ; initialize state buffer if $iInit = 1 (get device state on script start)
EndIf
If @error Then
$aUSBDevice[$iDev][2] = -1 ;error finding device
Return SetError(4, 0, -1)
EndIf
Next
Next

If $iCnt >= 1 Then Return SetError(0, 0, 1) ;one or more devices found
Return SetError(0, 0, 0) ;device(s) not found
EndFunc ;==>_FindUSBDeviceEx

I see fascists...

Link to comment
Share on other sites

I forgot about using a WMI sink...

Modified from basic WMI code for detecting USB drives in Wraithdu's Safely Eject a USB Drive thread

I think you will find this to be much faster using less code and no cpu spikes

;coded by rover 2k12
OnAutoItExitRegister("_OnExit")
HotKeySet("{ESC}", "_Stop")

;Array with property, property value, your command string
Global $aUSBDevProp[2][3] = [["Caption", "Apple iPod", "Whatever program1"],["PNPDeviceID", "USBSTOR\DISK&VEN_SAMSUNG&PROD_ANDROID&REV_FFFF\T499F99F0CB8&0", "Whatever program2"]]
;Global $aUSBDevProp[2][3] = [["PNPDeviceID", "USB\VID_045E&PID_02A1&IG_00\6&366022B6&1&00", "Whatever program1"], ["PNPDeviceID", "USB\VID_045E&PID_02A1&IG_02\6&366022B6&1&02", "Whatever program2"]]

Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
Global $oWMISink
_MonitorUSBDevices($oWMISink)
If @error Then Exit ConsoleWrite("! Error: " & @error & @LF)

ConsoleWrite("> Monitoring - Press ESC to Exit: " & @LF & @LF)
While 1
    Sleep(1000)
WEnd

Func _MonitorUSBDevices(ByRef $oObj)
    $oObj = ObjCreate("WbemScripting.SWbemSink")
    If @error Or Not IsObj($oObj) Then Return SetError(1, 0, -1)
    ObjEvent($oObj, "SINK_")
    If @error Then Return SetError(2, 0, -1)
    Local $Obj_WMIService = ObjGet('winmgmts:\\localhost\root\cimv2')
    If @error Or Not IsObj($oObj) Then Return SetError(3, 0, -1)
    $Obj_WMIService.ExecNotificationQueryAsync($oWMISink, "SELECT TargetInstance FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PnPEntity'")
EndFunc   ;==>_MonitorUSBDevices

Func SINK_OnObjectReady($objLatestEvent, $objAsyncContext)
    #forceref $objAsyncContext
    Switch $objLatestEvent.Path_.Class
        Case "__InstanceCreationEvent"
            For $i = 0 To UBound($aUSBDevProp) - 1
                If (Execute("$objLatestEvent.TargetInstance." & $aUSBDevProp[$i][0]) == $aUSBDevProp[$i][1]) Then
                    ConsoleWrite("+ Device Connected: " & $aUSBDevProp[$i][0] & ": " & $aUSBDevProp[$i][1] & @LF)
                    ConsoleWrite("- Run: " & $aUSBDevProp[$i][2] & @LF & @LF)
                    ;Run($aUSBDevProp[$i][2])
                EndIf
            Next
            ;ConsoleWrite("> Creation Event" & @CRLF)
            ;ConsoleWrite("Caption: " & $objLatestEvent.TargetInstance.Caption & @CRLF)
            ;ConsoleWrite("Name: " & $objLatestEvent.TargetInstance.Name & @CRLF)
            ;ConsoleWrite("Description: " & $objLatestEvent.TargetInstance.Description & @CRLF)
            ;ConsoleWrite("PNPDeviceID: " & $objLatestEvent.TargetInstance.PNPDeviceID & @CRLF)
            ;ConsoleWrite("DeviceID: " & $objLatestEvent.TargetInstance.DeviceID & @CRLF)
            ;ConsoleWrite("->==========================================" & @CRLF)
        Case "__InstanceDeletionEvent"
            For $i = 0 To UBound($aUSBDevProp) - 1
                If (Execute("$objLatestEvent.TargetInstance." & $aUSBDevProp[$i][0]) == $aUSBDevProp[$i][1]) Then
                    ConsoleWrite("! Device Disconnected: " & $aUSBDevProp[$i][0] & ": " & $aUSBDevProp[$i][1] & @LF & @LF)
                EndIf
            Next
            ;ConsoleWrite("> Deletion Event" & @CRLF)
    EndSwitch
EndFunc   ;==>SINK_OnObjectReady

Func _OnExit()
    ;$oWMISink.Cancel
    ConsoleWrite("Exiting." & @LF)
EndFunc   ;==>_OnExit

Func _Stop()
    ConsoleWrite("WMI Cancel was requested." & @LF)
    $oWMISink.Cancel ;use if you want to stop and start monitoring
    Exit
EndFunc   ;==>_Stop

; User's COM error function. Will be called if COM error occurs
Func _ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite("err.number is: " & @TAB & $oError.number & @CRLF & _
            "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            "err.description is: " & @TAB & $oError.description & @CRLF & _
            "err.source is: " & @TAB & $oError.source & @CRLF & _
            "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    Return SetError(1)
EndFunc   ;==>_ErrFunc

I see fascists...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...