hname Posted March 13, 2022 Posted March 13, 2022 Hello, Could anyone know why this code have following error. Quote "C:\HTHSystem\Runtime\testdevice4.au3" (20) : ==> Variable must be of type "Object".: $colitems = $objwmiservice.execquery("SELECT * FROM Win32_PnPEntity where Name LIKE '%Apple%' or Name Like '%adb%'") $colitems = $objwmiservice^ ERROR ->11:19:31 AutoIt3.exe ended.rc:1 If I run the code without GUIRegisterMsg($WM_DEVICECHANGE , "WM_DEVICECHANGE") or DeviceList(), it works fine. My idea is to use GUIRegisterMsg to detect any device event and then run DeviceList to find out which deviceID plug in. I can use only DeviceList() but it would require I run this function every 100 ms for detecting new devices. Thanks. $DBT_DEVNODES_CHANGED = 0x0007 $WM_DEVICECHANGE = 0x0219 Opt("GuiOnEventMode", 1) $hWnd = GUICreate("", 500, 120) GUISetState() GUIRegisterMsg($WM_DEVICECHANGE , "WM_DEVICECHANGE") While 1 Sleep(100) WEnd Func WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) If $wParam = $DBT_DEVNODES_CHANGED Then DeviceList() EndFunc Func DeviceList() Local $objwmiservice, $colitems $objwmiservice = ObjGet("winmgmts:\\localhost\root\CIMV2") $colitems = $objwmiservice.execquery("SELECT * FROM Win32_PnPEntity where Name LIKE '%Apple%' or Name Like '%adb%'") For $objitem In $colitems $sret = $objItem.DeviceID MsgBox(0,"",$sret) Next EndFunc
Nine Posted March 13, 2022 Posted March 13, 2022 (edited) I tested your code with my Win7 and AutoIt 3.3.16.0. I am not able to reproduce your issue. Everything went smoothly without any error (although I removed your where clause). What is your environment ? Edit : there is a MsgBox indirectly within your WinProc function. As per MSDN (and help file), it is not recommended to have a blocking function inside a WinProc. Maybe it could be the source of your issue. You could replace the MsgBox by a ConsoleWrite, see if it solves your problem. If it does and you still need a MsgBox, I suggest you create a GUICtrlCreateDummy() and send a message to it from the WinProc. Edited March 13, 2022 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
hname Posted March 13, 2022 Author Posted March 13, 2022 I removed msgbox (and even where condition in SQL query) in the DeviceList() Function. I also updated AutoIT to the newest version (AutoIt 3.3.16.0). I run the code on ThinkPad X1 Yoga Windows 10 Pro. Still same error on another Windows 10 Pro Computer. I don't have Windows 7 to test it on.
hname Posted March 13, 2022 Author Posted March 13, 2022 (edited) It may be a little bit of confused when I post this code without any example. Below is how I run it: You need to have at least an android phone with Developer Mode on or an iPhone. You need to authorize the device connection when asked by your phone devices the first time to plug it in USB port. First, run my code above. Second, plug the phone in or remove it if it was plugged. The Error code will shown up If you did not plug the phone in or remove it, there's no device event change and of course no error. If you removed the GUIRegisterMsg($WM_DEVICECHANGE , "WM_DEVICECHANGE"), and run DeviceList() only, there's no error. That's why I suspect something went conflicted when use GUIRegisterMsg($WM_DEVICECHANGE , "WM_DEVICECHANGE"), and COM Object together. Any help please. Otherwise, I have to use a While Loop to detect new devices every 100 ms. Edited March 13, 2022 by hname Private info
Nine Posted March 14, 2022 Posted March 14, 2022 (edited) Did you try with other devices like keyboard, or USB memory key ? Do you get also an error or is it only with your cellular phones ? I cannot test it now on a Win10 and with an Android phone. I'll see tomorrow if I can replicate your issue, otherwise it is going to be very hard for me to help you. In the mean time, put a COM error handler and provide the error code, so we know a bit more why the statement is failing. Also try running x64 and #RequireAdmin, see if those can change anything. Edited March 14, 2022 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
Solution hname Posted March 14, 2022 Author Solution Posted March 14, 2022 (edited) Thank you very much Nine. I found why the code have error: From GUIRegisterMsg help page: Quote Warning: blocking of running user functions which executes window messages with commands such as "MsgBox()" can lead to unexpected behavior, the return to the system should be as fast as possible !!! So If I put a delay 5000 ms in the if condtion Func WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) If $wParam = $DBT_DEVNODES_CHANGED Then sleep(5000) $deviceID = DeviceList() MsgBox(0,"", $deviceID) EndIf EndFunc Then it works perfectly. However, anything less than 5000 ms will give rise to the error. I don't know the reason why but It could be from the Warning above, It is weird that I have to wait at least 5 seconds to call the WMI query. To skip this delay, I can put a Global Boolean variable in the WM_DEVICECHANGE function and run DeviceList() function whenever the boolean variable return TRUE. Solved. Once again, thank you for your suggestion. Edited March 14, 2022 by hname
Nine Posted March 14, 2022 Posted March 14, 2022 (edited) 10 hours ago, hname said: the return to the system should be as fast as possible !!! But you are delaying even more by putting a long Sleep and using MsgBox. This is not a solution. Like I told you previously, you should use a CtrlDummy and send a message to it. From that control, you can then wait as long as you want and use any blocking function as you wish to... To understand why it is failing we would need to know the error causing it query to fail. A COM error handler will capture the error code. I was not able to replicate your issue on Win10. Here the code that you should try to run : expandcollapse popup#include <GUIConstants.au3> Global Const $DBT_DEVNODES_CHANGED = 0x0007 Global $oErrorHandler = ObjEvent("AutoIt.Error", ErrorFunc) Global $hWnd = GUICreate("") Global $idDummy = GUICtrlCreateDummy() GUIRegisterMsg($WM_DEVICECHANGE, WM_DEVICECHANGE) GUISetState() While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idDummy ConsoleWrite("Message was sent" & @CRLF) DeviceList() EndSwitch WEnd Func WM_DEVICECHANGE($hWnd, $iMsg, $wParam, $lParam) If $wParam = $DBT_DEVNODES_CHANGED Then ConsoleWrite("Notification received" & @CRLF) GUICtrlSendToDummy($idDummy) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_DEVICECHANGE Func DeviceList() Local $objwmiservice, $colitems $objwmiservice = ObjGet("winmgmts:\\localhost\root\CIMV2") $colitems = $objwmiservice.execquery("SELECT * FROM Win32_PnPEntity where Name = 'Moto G Play'") For $objitem In $colitems MsgBox(0, "WMI", $objitem.Caption & @CRLF & $objItem.DeviceID) Next EndFunc ;==>DeviceList Func ErrorFunc($oError) ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>ErrorFunc Edited March 14, 2022 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
hname Posted March 15, 2022 Author Posted March 15, 2022 Your code works very well. It's good to know that GUICtrlCreateDummy() trick can be used to call DeviceList() (which is better IMO) instead of using a Boolean variable as in my case. Thanks for your code. Regards,
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