Jump to content
Sign in to follow this  
jvalenc

IE.au3 IEAttach

Recommended Posts

jvalenc

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()))

Share this post


Link to post
Share on other sites
PsaltyDS

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.

:mellow:


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

Share this post


Link to post
Share on other sites
jvalenc

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.

:mellow:

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.

Share this post


Link to post
Share on other sites
PsaltyDS

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.

:mellow:


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

Share this post


Link to post
Share on other sites
Samoth

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
    ;--------------

Share this post


Link to post
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
Sign in to follow this  

×