EmilyLove Posted September 25, 2016 Share Posted September 25, 2016 (edited) First, I have to say im terrible at com objects. I got this code somewhere (I forgot where) and somehow managed to modify it to fit my needs. The script currently reads from the list of hardware id that is currently connected to the system and checks for a certain id in that list. This is pretty resource intensive on my system. Adding sleep to it makes it more manageable, however it takes a lot longer to detect newly connected hardware. How do I get it to only check for a specific id? The ID I'm looking for is "USB\VID_045E&PID_02E4&IGA_00" expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_UseUpx=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;Written By: Amin Babaeipanah ;Modified By: BetaLeaf opt("TrayIconHide",1) $winTitle = "Xbox One Headset Auto Connection" $WorkingDirectory = @TempDir & "\BetaLeaf Software\" & $winTitle DirCreate(@TempDir & "\BetaLeaf Software\" & $winTitle) FileInstall("nircmdc.exe", @TempDir & "\BetaLeaf Software\" & $winTitle & "\nircmdc.exe", 1) Setup() While 1 If GetDevices("") = 1 Then For $i = 0 To 2 ShellExecute($WorkingDirectory & "\NIRCMDC.exe", 'setdefaultsounddevice "Headphones" ' & $i & '"', @ScriptDir, "", @SW_HIDE) ;Set Default Playback Device to Slot $Slot. Next For $i = 0 To 2 ShellExecute($WorkingDirectory & "\NIRCMDC.exe", 'setdefaultsounddevice "Headset Microphone" ' & $i & '"', @ScriptDir, "", @SW_HIDE) ;Set Default Recording Device to Slot $Slot. Next Do Sleep(5000) Until GetDevices("") = 2 EndIf Sleep(5000) WEnd Func GetDevices($name) Local $objWMIService = ObjGet('winmgmts:\\localhost\root\CIMV2') Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%" & $name & "%'", "WQL", 48) If IsObj($colItems) Then For $objItem In $colItems Select Case StringInStr($objItem.PNPDeviceID, "USB\VID_045E&PID_02E4&IGA_00") <> 0 Return 1 EndSelect sleep(50) Next EndIf Return 2 EndFunc ;==>GetDevices Func Setup() Local $StartwithWindows = RegRead("HKCU\Software\BetaLeaf Software\Xbox One Headset Auto Connection", "StartwithWindows") If @error Then Local $ret = MsgBox(64 + 4, $winTitle, "Would you like this program to Start with Windows?") If $ret = 6 Then If RegWrite("HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", $winTitle, "REG_SZ", '"' & @ScriptFullPath & '"') = 0 Then MsgBox(0, $winTitle, "Could not write to registry. Error: " & @error) If RegWrite("HKCU\Software\BetaLeaf Software\Xbox One Headset Auto Connection", "StartwithWindows", "REG_DWORD", "1") = 0 Then MsgBox(16, $winTitle, "Could not write to registry. Error: " & @error) ElseIf $ret = 7 Then If RegDelete("HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", $winTitle) = 2 Then MsgBox(0, $winTitle, "Could not delete registry key. Error: " & @error) If RegWrite("HKCU\Software\BetaLeaf Software\Xbox One Headset Auto Connection", "StartwithWindows", "REG_DWORD", "0") = 0 Then MsgBox(16, $winTitle, "Could not write to registry. Error: " & @error) EndIf Else Local $Run = RegRead("HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", $winTitle) Select Case @error = -1 If RegDelete("HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", $winTitle) = 2 Then MsgBox(0, $winTitle, "Could not delete registry key. Error: " & @error) If RegWrite("HKCU\Software\BetaLeaf Software\Xbox One Headset Auto Connection", "StartwithWindows", "REG_DWORD", "0") = 0 Then MsgBox(16, $winTitle, "Could not write to registry. Error: " & @error) Case $Run <> "" If RegWrite("HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", $winTitle, "REG_SZ", '"' & @ScriptFullPath & '"') = 0 Then MsgBox(0, $winTitle, "Could not write to registry. Error: " & @error) If RegWrite("HKCU\Software\BetaLeaf Software\Xbox One Headset Auto Connection", "StartwithWindows", "REG_DWORD", "1") = 0 Then MsgBox(16, $winTitle, "Could not write to registry. Error: " & @error) Case Else MsgBox(16, $winTitle, "Could not read registry. Error: " & @error) EndSelect EndIf EndFunc ;==>Setup Edit: Solution at Edited September 28, 2016 by BetaLeaf Link to comment Share on other sites More sharing options...
Tripredacus Posted September 27, 2016 Share Posted September 27, 2016 Have you cut out the WMI query and run it on its own to verify that it is what is causing the slowdown? The only question I have, is you are specifying additionally "WQL" and 48 in your query, but I don't know what that does. Twitter | MSFN | VGCollect Link to comment Share on other sites More sharing options...
EmilyLove Posted September 27, 2016 Author Share Posted September 27, 2016 43 minutes ago, Tripredacus said: Have you cut out the WMI query and run it on its own to verify that it is what is causing the slowdown? The only question I have, is you are specifying additionally "WQL" and 48 in your query, but I don't know what that does. I have no idea. I don't even know how I got it to work at all. I do not understand com objects yet. I'm pretty sure it's the function getdevices that causes the slowdown. Adding sleep(10) in the for next loop reduces the slowdown but increases search time exponentially. I have a lot of devices connected to this computer. Link to comment Share on other sites More sharing options...
jguinch Posted September 27, 2016 Share Posted September 27, 2016 Backslashes have to be escaped. Try this : select * from Win32_PnPEntity Where PNPDeviceID = 'USB\\VID_045E&PID_02E4&IGA_00' Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
kylomas Posted September 27, 2016 Share Posted September 27, 2016 "WQL" = SQL for WMI 48 = wbemFlagForwardOnly (32 (0x20)) + wbemFlagReturnImmediately (16 (0x10)) ref - https://msdn.microsoft.com/en-us/library/aa393866(v=vs.85).aspx As our martian friend suggests, break out the code you suspect or put some timing diagnostics in the existing code. 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 More sharing options...
EmilyLove Posted September 27, 2016 Author Share Posted September 27, 2016 I still can't get it to work. What am I doing wrong? Local $colItems = $objWMIService.ExecQuery("select * from Win32_PnPEntity Where PNPDeviceID = 'USB\\VID_045E&PID_02E4&IGA_00'", "WQL", 48) Local $colItems = $objWMIService.ExecQuery('select * from Win32_PnPEntity Where PNPDeviceID = "USB\\VID_045E&PID_02E4&IGA_00"', "WQL", 48) I've also tried checking for @errors and using Consolewrite to check values. I'm not getting anything that will lead me to a solution. Values are blank with the above code. On the existing code I have, it returns every device id connected to this computer when I place the check in the For next loop. Link to comment Share on other sites More sharing options...
Tripredacus Posted September 28, 2016 Share Posted September 28, 2016 (edited) I brought up the WQL and 48 because I've never used those in a WMI query. For "breakout" purposes, I personally keep a dedicated au3 for just doing WMI testing. Here is one example... #include <file.au3> #include <array.au3> #Include <String.au3> Global $bin Global $sWMIService, $objWMIService, $colDisks, $sNumber $sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2" $objWMIService = ObjGet($sWMIService) IF IsObj($objWMIService) Then $colDisks = $objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard") If IsObj($colDisks) Then For $oItem In $colDisks $sNumber = $oItem.Manufacturer MsgBox (4096, "Manufacturer", "looks at this Manufacturer: " & $sNumber & ".") Next Else MsgBox (4096, "Error", "colDisks data is empty") EndIf EndIf Now my labels and declarations may not match up, as I use it as a scratch pad ALOT, but it should work or you get the idea. I have only 1 similar au3 I can find at the moment that uses LIKE, but I am not looking specifically for a hardware ID in the query because it can be troublesome. Instead I can look for the description that Windows has on the item. In this example, I am looking for devices that have Fingerprint in their name. Because I know that the 2 things I am looking for will always be using this term. $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%Fingerprint%'") I use the WMI to find me all instances of Fingerprint, and store that info. I am using LIKE because I am looking for 2 different results that have that word in it. If you are looking for an exact match, you do not need to use LIKE. When designing what type of WMI query you should use, it is extremely helpful to be able to see the tables. For Windows 7 (or IE8/9 and older) MS had made a browser plugin called WMI Explorer. It does not work well now, and it is possible there are other WMI viewers for current versions of Windows. Otherwise, if you have a testing au3 to run tests either as singular messagebox on a match scenario, or output an entire WMI table for viewing, this can be done also. We can compare it directly to doing *sql queries. In those situations, you know the structure of the database and what the data is supposed to be, then you build your query to get the appropriate data to be returned to do whatever. WMI is no different. Aside from the simple things such as seeing what 1 field happens to have in it, you should really see what everything is in order to build your query correctly and/or use the data. An idea: if you feel there is a problem with the slashes being in the data, you can trim the USB\\ part off your comparison so you end up not using it at all. EDIT: here is a test au3 I make to help me see what the HardwareIDs are. It will find how many instance have mouse, then show me the hardwareID. It finds 2 instances, but the field is empty. #include <file.au3> #include <array.au3> #Include <String.au3> Global $bin Global $sWMIService, $objWMIService, $colDisks, $DiskDrive, $DriveLetter, $DriveType, $VolumeName, $sNumber, $sName $sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2" $objWMIService = ObjGet($sWMIService) IF IsObj($objWMIService) Then $colDisks = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE Description LIKE '%mouse%'") If IsObj($colDisks) Then For $oItem In $colDisks $sNumber = $oItem.HardwareID MsgBox (4096, "Mouse HwID", "look at this HardwareID: " & $sNumber & ".") Next EndIf EndIf Here is a link to the class, I didn't see it posted here yet. https://msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx Edited September 28, 2016 by Tripredacus Twitter | MSFN | VGCollect Link to comment Share on other sites More sharing options...
jguinch Posted September 28, 2016 Share Posted September 28, 2016 (edited) I think your problem comes from the operator "= ". Replace it by "like" and add "%" at this end of the string. Look : Local $oDevice, $PNPDeviceID, $sHardwareIDs, $oWMIService = ObjGet("winmgmts:\\.\root\CIMV2") If Not IsObj($oWMIService) Then Exit MsgBox(16, "Error", "WMI error") Local $oPNPDevices = $oWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB\\VID%'", "WQL", 48) If IsObj($oPNPDevices) Then For $oDevice In $oPNPDevices $sHardwareIDs = "" $PNPDeviceID = $oDevice.PNPDeviceID $aHardwareID = $oDevice.HardwareID For $i = 0 To UBound($aHardwareID) - 1 $sHardwareIDs &= $aHardwareID[$i] & @CRLF Next MsgBox (4096, "PNPDeviceID found", "PNPDeviceID : " & $PNPDeviceID & @CRLF & "HardwareID : " & $sHardwareIDs) Next EndIf As you can see, HardwareID is no a string but an array of strings. See here : https://msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx Also, you can check out your query result with a graphic tool, it would be easier. Try with WMIExlorer Edited September 28, 2016 by jguinch EmilyLove 1 Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
kylomas Posted September 28, 2016 Share Posted September 28, 2016 FWIW - I use this to enumerate cimv2 class properties expandcollapse popup#include <array.au3> local $ret = _WMI('win32_pnpentity') ;local $ret = _WMI('Win32_bios') If @error Then Exit (ConsoleWrite(@LF & '!> @ERROR = ' & @error & @LF & '!> @EXTENDED = ' & @extended & @LF & '!> $RET = ' & $ret & @LF & @LF)) If IsArray($ret) Then _ArrayDisplay($ret) If IsString($ret) Then ConsoleWrite($ret & @CRLF) ; #FUNCTION# ==================================================================================================================== ; Name...........: _WMI ; Description ...: Returns formatted output from a query against any class of the CIMV2 namespace using WMI. ; Syntax.........: _WMI($sWQL, $bReturnType, $sDelimiter, $sTargetPC) ; Parameters ....: $sWQL - Any class in the WMI CIMV2 namespace (e.g. Win32_Process, Win32_BIOS, Win32_Desktop, etc.) ; or any WQL 'Select' query. If only the class is specified then all columns ; for all items are returned. ; $bReturnType - Indicates return format. $bReturnType can be a string or integer. ; |0 - Return a 2D array with item names in col 0 (on the left). ; |1 - Return a 2D array with item names in row 0 (on top). (DEFAULT) ; |2 - Return a @CRLF delimited string of item names (row #1) followed by items. Each value is ; delimited by $sDelimiter. ; $sDelimiter - The delimiter used to seperate values/property names within an item. The default is ; '`' because other common delimiter characters (e.g. '|', ',', '=', ':', '~' etc. appear ; in some values returned by various WQL queries. This can be a string of characters (e.g. '//'). ; $sTargetPC - Name of the PC to run the query on. ; Return values .: Success - A 2D array or string depending on $bReturnType. ; Failure - Sets @ERROR and returns a value as follows: ; |1 - $sWQL is blank Return value - None ; |2 - $bReturnType invalid Return value - The parm supplied ; |3 - $sDelimiter not specified Return value - None ; |4 - WMI ObjGet failure Return value - None ; |5 - ExecQuery failure Return value - $sWQL ; |6 - No items returned Return value - $sWQL ; ; Author ........: kylomas ; Modified.......: 02/02/2015 V01R01M01 initial release ; Remarks .......: ; Related .......: WMI is required ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WMI($sWQL, $bReturnType = 1, $sDelimiter = '`', $sTargetPC = @ComputerName) ; flush parms Switch $bReturnType Case 0, 1, 2, '0', '1', '2' Case -1, Default $bReturnType = 1 Case Else Return SetError(2, 0, $bReturnType) EndSwitch Switch True Case $sDelimiter = -1 Or $sDelimiter = Default $sDelimiter = '`' Case StringLen($sDelimiter) > 0 Case Else Return SetError(3, 0, $sDelimiter) EndSwitch If StringLen($sWQL) = 0 Then Return SetError(1) If StringInStr($sWQL, 'select') = 0 Then $sWQL = 'select * from ' & $sWQL Local $oWMI = '', $oItem = '', $oItems = '', $P = '' ; Get WMI instance ; Do NOT use $wbemFlagReturnImmediately or $wbeForwardOnly as this disables the "Count" property $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sTargetPC & "\root\CIMV2") If Not IsObj($oWMI) Then Return SetError(4) ; Run query $oItems = $oWMI.ExecQuery($sWQL) If Not IsObj($oItems) Then Return SetError(5, 0, $sWQL) If $oItems.count = 0 Then Return SetError(6, 0, $sWQL) Local $str = '' ; format header / use this method as opposed to the "itemindex" method for XP compatibility For $oItem In $oItems For $P In $oItem.Properties_() $str &= '<' & $P.Name & '>' & $sDelimiter Next $str = StringTrimRight($str, StringLen($sDelimiter)) & @CRLF ExitLoop Next ; format each detail item For $oItem In $oItems For $P In $oItem.Properties_() Switch True Case $P.isarray $aTmp1 = $P.Value $str &= _ArrayToString($aTmp1) & $sDelimiter Case $P.CIMTYPE = 101 $str &= CNVTDate($P.Value) & $sDelimiter Case Else $str &= $P.Value & $sDelimiter EndSwitch Next $str = StringTrimRight($str, StringLen($sDelimiter)) & @CRLF Next $str = StringTrimRight($str, 2) Switch $bReturnType Case '1', 1, -1, Default ; return 2D array / column names are at top (row 0) Local $aTmp1 = StringSplit($str, @CRLF, 3), $aTmp2 Local $aRet[UBound($aTmp1)][UBound(StringSplit($aTmp1[0], $sDelimiter, 3))] For $1 = 0 To UBound($aTmp1) - 1 $aTmp2 = StringSplit($aTmp1[$1], $sDelimiter, 3) For $2 = 0 To UBound($aTmp2) - 1 $aRet[$1][$2] = $aTmp2[$2] Next Next Return $aRet Case '0', 0 ; return 2D array / column names are to the left (col 0) Local $aTmp1 = StringSplit($str, @CRLF, 3), $aTmp2 Local $aRet[UBound(StringSplit($aTmp1[0], $sDelimiter, 3))][UBound($aTmp1)] For $1 = 0 To UBound($aTmp1) - 1 $aTmp2 = StringSplit($aTmp1[$1], $sDelimiter, 3) For $2 = 0 To UBound($aTmp2) - 1 $aRet[$2][$1] = $aTmp2[$2] Next Next Return $aRet Case '2', 2 ; return string Return $str Case Else Return SetError(7, 0, $bReturnType) EndSwitch EndFunc ;==>_WMI Func CNVTDate($dtmDate) ; reformat date to mm/dd/yyyy hh:mm:ss and zero fill single digit values Return StringRegExpReplace(StringRegExpReplace($dtmDate, '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).*', '$2/$3/$1 $4:$5:$6'), '(?<!\d)(\d/)', '0$1') EndFunc ;==>CNVTDate Array values are separated by a '|' kylomas jguinch 1 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 More sharing options...
EmilyLove Posted September 28, 2016 Author Share Posted September 28, 2016 (edited) 32 minutes ago, jguinch said: This works : Local $oDevice, $PNPDeviceID, $oWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") If Not IsObj($oWMIService) Then Exit MsgBox(16, "Error", "WMI error") Local $oPNPDevices = $oWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB\\VID%'", "WQL", 48) If IsObj($oPNPDevices) Then For $oDevice In $oPNPDevices $PNPDeviceID = $oDevice.PNPDeviceID MsgBox (4096, "PNPDeviceID found", "PNPDeviceID : " & $PNPDeviceID) Next EndIf Did you try with % ? Where PNPDeviceID like "USB\\VID_045E&PID_02E4&IGA_00%" Also, you can check out your query result with a graphic tool, it would be easier. Try with WMIExlorer The WMIExplorer tool helped me figure out the issue. The problem was I was searching for SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%%' a Win32_PnPEntity where it's name could be anything. Thus, when I tried to specify a name, SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%USB\\VID_045E&PID_02E4&IGA_00%' it returned nothing because I wasn't inputting a name, I was inputting a DeviceID. Changing it to SELECT * FROM Win32_PnPEntity WHERE DeviceID Like '%USB\\VID_045E&PID_02E4&IGA_00%' gave me the device I was looking for. This is going in my Xbox-One-Headset-AutoConnection script on Github. Would you like to be mentioned as a Contributor, @jguinch? Edited September 28, 2016 by BetaLeaf Xandy 1 Link to comment Share on other sites More sharing options...
jguinch Posted September 28, 2016 Share Posted September 28, 2016 (edited) @BetaLeaf : as you wish, it does not matter to me. It's just a pleasure to help edit : @kylomas : I like your WMI function, nice and usefull ! Edited September 28, 2016 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
EmilyLove Posted September 28, 2016 Author Share Posted September 28, 2016 Just now, jguinch said: @BetaLeaf : as you wish, it does not matter to me. It's just a pleasure to help I will add you to the contributors list then. Thanks to everyone for your help, especially @jguinch. Link to comment Share on other sites More sharing options...
jguinch Posted September 28, 2016 Share Posted September 28, 2016 @kylomas : Switch True = Select Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
EmilyLove Posted September 28, 2016 Author Share Posted September 28, 2016 1 minute ago, jguinch said: @kylomas : Switch True = Select Lol I didn't notice that the first time. Wonder why they did that? Link to comment Share on other sites More sharing options...
kylomas Posted September 28, 2016 Share Posted September 28, 2016 Where do you guys see Switch True = Select? 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 More sharing options...
jguinch Posted September 29, 2016 Share Posted September 29, 2016 It was a little joke about your code, because of the use of "Switch True". I thought you forgot the use of Select. Sorry, i'm not good with jokes in english. EmilyLove 1 Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
genius257 Posted October 2, 2016 Share Posted October 2, 2016 (edited) Hi @BetaLeaf I know it's solved, but i have a suggestion that should be better for your cpu and for the execution time of the code. First an example, showing time difference between what i understand is currently the solution and my proposal. #include <APISysConstants.au3> #include <WinAPISys.au3> $oWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") $vTime = TimerInit() $oPNPDevices = $oWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE DeviceID LIKE '%USB\\VID_045E&PID_02E4%'", "WQL", 48) ConsoleWrite(TimerDiff($vTime)&@CRLF) $vTime = TimerInit() $aData = _WinAPI_EnumRawInputDevices() $tText = DllStructCreate('wchar[256]') $sPattern = "[Vv][Ii][Dd]_045E&[Pp][Ii][Dd]_02E4" For $i=0 To UBound($aData, 1)-1 _WinAPI_GetRawInputDeviceInfo($aData[$i][0], $tText, 256, $RIDI_DEVICENAME) If StringRegExp(DllStructGetData($tText, 1), $sPattern) Then ConsoleWrite(DllStructGetData($tText, 1)&@CRLF) Next ConsoleWrite(TimerDiff($vTime)&@CRLF) Here's the example with WM_DEVICECHANGE to save cpu usage: expandcollapse popup#include <APISysConstants.au3> #include <WinAPISys.au3> Global Const $sVID = "045E" Global Const $sPID = "02E4" $bSwitch = False; used to check if action needs to be taken, on WM_DEVICECHANGE $DBT_DEVICEARRIVAL = "0x00008000" $DBT_DEVNODES_CHANGED = 0x0007 $WM_DEVICECHANGE = 0x0219 Opt("GuiOnEventMode", 1) $hWnd = GUICreate("", 700, 320) GUISetOnEvent(-3, "_MyExit", $hWnd) GUISetState() Alternative();call to check for device, before event listening GUIRegisterMsg($WM_DEVICECHANGE , "WM_DEVICECHANGE") While 1 Sleep(10) WEnd Func WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) If $wParam = $DBT_DEVNODES_CHANGED Then Alternative() EndFunc Func Alternative() Local $aDevices = _WinAPI_EnumRawInputDevices() Local $tText = DllStructCreate('wchar[256]') Local $sPattern = "[Vv][Ii][Dd]_"&$sVID&"&[Pp][Ii][Dd]_"&$sPID For $i=0 To UBound($aDevices, 1)-1 _WinAPI_GetRawInputDeviceInfo($aDevices[$i][0], $tText, 256, $RIDI_DEVICENAME) If StringRegExp(DllStructGetData($tText, 1), $sPattern) Then ;~ ConsoleWrite(DllStructGetData($tText, 1)&@CRLF) If $bSwitch Then Return $bSwitch = True ConsoleWrite("element inserted, action taken"&@CRLF) ;do stuff here Return EndIf Next If Not $bSwitch Then Return $bSwitch = False ConsoleWrite("element removed, action taken"&@CRLF) EndFunc Func _MyExit() Exit EndFunc And time could be reduced further if the for loop did not need _WinAPI_EnumRawInputDevices, but rather processed each match as needed from the GetRawInputDeviceList dllcall Edited October 2, 2016 by genius257 Chaged $sVID and $sPID values My highlighted topics: AutoIt Package Manager, AutoItObject Pure AutoIt, AutoIt extension for Visual Studio Code Github: AutoIt HTTP Server, AutoIt HTML Parser Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now