jvalenc Posted March 9, 2010 Posted March 9, 2010 I was using the following code as a general way to have scripts run against the next browser selected. WinWaitActive("[CLASS:IEFrame]") Dim $olsHandle = WinGetHandle ( "[CLASS:IEFrame]" ) Dim $oIE = _IEAttach ($olsHandle, "HWND") When I switched to my new laptop the scripts stopped working. I have found what I think is the issue. First here is the error I get when running in SCITE E:\Bin\autoit\install\Include\IE.au3 (2674) : ==> The requested action with this object has failed.: Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd())) Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd()^ ERROR ->16:21:10 AutoIT3.exe ended.rc:1 Looking into the code I think this is the issue. Basically I created the following code to reproduce the issue Local $o_Shell = ObjCreate("Shell.Application") Local $o_ShellWindows = $o_Shell.Windows(); collection of all ShellWindows (IE and File Explorer) Local $i=0; ;MsgBox( 0, "Count", $o_ShellWindows.Count ); For $o_window In $o_ShellWindows MsgBox( 0, $i, $o_window.Name() & @CrLf & $o_window.locationURL() ); MsgBox( 0, $i, $o_window.Hwnd() ); $i = $i + 1; Next What I found the issue to be is the call $o_window.Hwnd(). When I run this code I get 3 as the Count. In order this is output ---- Microsoft Internet Explorer file://.../xx.html --- 12341234 ---- Microsoft Internet Explorer file://.../xx.html ---- 12341324 ---- Microsoft Web Browser Control file://.../xx.html ---- Script crashes here trying to get new HWND So with the name of the .html I was able to find the application causing the problem. IBM has a program called "IBM Help" This program has an icon in the task bar, and I believe it has other processes running in the background. When I kill the application the scripts work. My question is, is there a bug here. Should the logic calling the problem method "_IEGetObjByName" be better protected? Case "hwnd" If $i_instance > 1 Then $i_instance = 1 __IEErrorNotify("Warning", "_IEAttach", "$_IEStatus_GeneralError", "$i_instance > 1 invalid with HWnd. Setting to 1.") EndIf If _IEPropertyGet($o_window, "hwnd") = $s_string Then Return SetError($_IEStatus_Success, 0, $o_window) EndIf Case Else Or the logic in the method itself Func _IEPropertyGet(ByRef $o_object, $s_property) ... Case $s_property = "hwnd" If Not __IEIsObjType($o_object, "browser") Then __IEErrorNotify("Error", "_IEPropertyGet", "$_IEStatus_InvalidObjectType") Return SetError($_IEStatus_InvalidObjectType, 1, 0) EndIf Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd()))
PsaltyDS Posted March 9, 2010 Posted March 9, 2010 You left this code from the real _IEAttach() out of your simulation, which is why it crashes when it hits the IBM application's ShellWindow: ; Trap COM errors and turn off error notification $status = __IEInternalErrorHandlerRegister() If Not $status Then __IEErrorNotify("Warning", "_IEAttach", _ "Cannot register internal error handler, cannot trap COM errors", _ "Use _IEErrorHandlerRegister() to register a user error handler") $f_NotifyStatus = _IEErrorNotify() ; save current error notify status _IEErrorNotify(False) That was put in specifically because there are ShellWindows that fail in various ways during this check. I have no idea what "...a general way to have scripts run against the next browser selected" means, so I can't address your exact usage. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
jvalenc Posted March 9, 2010 Author Posted March 9, 2010 You left this code from the real _IEAttach() out of your simulation, which is why it crashes when it hits the IBM application's ShellWindow: ; Trap COM errors and turn off error notification $status = __IEInternalErrorHandlerRegister() If Not $status Then __IEErrorNotify("Warning", "_IEAttach", _ "Cannot register internal error handler, cannot trap COM errors", _ "Use _IEErrorHandlerRegister() to register a user error handler") $f_NotifyStatus = _IEErrorNotify() ; save current error notify status _IEErrorNotify(False) That was put in specifically because there are ShellWindows that fail in various ways during this check. I have no idea what "...a general way to have scripts run against the next browser selected" means, so I can't address your exact usage. Basically, I want the au3 script to run against the next instance of IE that is activated. Here is a very simple script that is having the same issue. Capture IE snapshot to ClipBoard ( used to paste screen shots of IE into documents by testers ) #include <IE.au3> #include <ScreenCapture.au3> WinWaitActive("[CLASS:IEFrame]") Dim $handle = WinGetHandle ( "[CLASS:IEFrame]" ) Dim $oIE = _IEAttach ($handle, "HWND") Sleep(1000) Send( "{ALTDOWN}{PRINTSCREEN}{ALTUP}" ) Another bit of code to do what I need is Dim $handle = WinGetHandle ( "[CLASS:IEFrame]" ) Dim $title = StringMid ( WinGetTitle($handle, ""),1, 10 ) Dim $oIE = _IEAttach ($title) You are correct I did not include that code into my example script. When I run my scripts I never see this error message output. I changed the DEBUG flag for IE.au3 script and this is what output was >Running:(3.3.4.0):E:\Bin\autoit\install\autoit3.exe "E:\Bin\src\Scripts\AutoIt\Tools\web\xprs_screencapture.au3" --> COM Error Encountered in xprs_screencapture.au3 ----> $IEComErrorScriptline = 395 ----> $IEComErrorNumberHex = 80020009 ----> $IEComErrorNumber = -2147352567 ----> $IEComErrorWinDescription = No such interface supported ----> $IEComErrorDescription = ----> $IEComErrorSource = ----> $IEComErrorHelpFile = ----> $IEComErrorHelpContext = 0 ----> $IEComErrorLastDllError = 1008 E:\Bin\autoit\install\Include\IE.au3 (2675) : ==> The requested action with this object has failed.: Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd())) Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd()^ ERROR ->21:15:10 AutoIT3.exe ended.rc:1 >Exit code: 1 Time: 4.143 So, I"m not sure that I understand if this is a issue should be happening or not. Basically the code when running now, just stops, and the reason is the window it comes across does not have HWND property set.
PsaltyDS Posted March 9, 2010 Posted March 9, 2010 It's actually a COM method being called ".hwnd()", not just a property retrieved. The presumption is that when it hits the ShellWindow instance of this IBM app, that attempted call fails in such a way that even the "silent" COM error handler still crashes the script. I don't know what's special about this app, or the error it throws. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Samoth Posted July 11, 2011 Posted July 11, 2011 You can modify your IE.au3 to check whether your IE object is a TopLevelContainer and respond accordingly in Func _IEPropertyGet(ByRef $o_object, $s_property) from line 2669 on: Case $s_property = "hwnd" If Not __IEIsObjType($o_object, "browser") Then __IEErrorNotify("Error", "_IEPropertyGet", "$_IEStatus_InvalidObjectType") Return SetError($_IEStatus_InvalidObjectType, 1, 0) EndIf ;Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd())) ;-------------- If $o_object.TopLevelContainer Then Return SetError($_IEStatus_Success, 0, HWnd($o_object.HWnd())) Else Return SetError($_IEStatus_Success, 0, 0) EndIf ;--------------
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