Jump to content

Problems automating an Internet Explorer_Server control


Recommended Posts

Hi lads,

I'm creating a script that after a fresh OS install, will automatically install my favourite apps (firefox, VideoLan, Winamp, AutoIT ;-) etc...) So far I've been quite successful, as I can perform silent installations for most of them... However, I'm having trouble when it comes to install the Antivirus software.

I'm using McAfee Total Protection, that came on a CD with my brand new DELL PC. When I execute the autorun (CDSetup.exe) I get a fancy installation menu, showing options like "Install McAfee Total Protection", "Install Acrobat Reader", "Browse the CD", "View Readme" and so for (See link at the bottom)

I was expecting that those menu elements were easily recognized by AutoIT's Window Info Tool, however the whole thing shows up as an "Internet Explorer_Server" control, and I cannot access the menu items individually.

At this point I still had hope, as other times that I came across the "Internet Explorer_Server" control I was able to access the "HTML" behind, and manipulate the DOM elements using the fantastic IE.au3 library.

But in this particular case, I can get the reference to the $oIE using the auxiliar function _ObjGetFromHWND but not much more...

A snippet of my code is as follows:

#include <IE.au3>

_IEErrorHandlerRegister()

$h_Win = WinGetHandle("McAfee CDSetup")
WinActivate($h_Win)
$h_Ctrl = ControlGetHandle($h_Win, "", "[Class:Internet Explorer_Server]") ; As shown by Window Info...
$o_IE = _ObjGetFromHWND($h_Ctrl)

If IsObj($o_IE) Then
    ConsoleWrite("Got the IE Object" & @CRLF)
    ConsoleWrite(ObjName($o_IE) & @CRLF); This shows "DispHTMLWindow2" so should be a Window, Frame or iFrame?
  ; The following 2 statements raise errors:
    $o_Doc = _IEDocGetObj($o_IE)
   ; COM error description is "Access Denied", regular error is "ie.au3 (2443) The requested action with this object has failed: Return $o_IE.document^ ERROR
    $s_HTML = _IEDocReadHTML($o_IE)
   ; COM error description is "Access Denied", regular error is "ie.au3 (2208) The requested action with this object has failed: Return $o_IE.document^ ERROR
    _IENavigate($o_IE, "www.autoitscript.com"); This worked
Else
    ConsoleWrite("Not an object" & @CRLF)
Endif

Func _ObjGetFromHWND(ByRef $hWin)
    DLLCall("ole32.dll","int","CoInitialize","ptr",0)
    If @error Then Return SetError(@error,@extended,0)

    Local Const $WM_HTML_GETOBJECT = _RegisterWindowMessage("WM_HTML_GETOBJECT")
    If @error Then Return SetError(@error,@extended,0)
    
    Local Const $SMTO_ABORTIFHUNG = 0x0002
    Local $lResult, $typUUID, $aRet, $oIE

    _SendMessageTimeout($hWin, $WM_HTML_GETOBJECT, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lResult)
    If @error Then Return SetError(@error,@extended,0)

    $typUUID = DLLStructCreate("int;short;short;byte[8]")
    DLLStructSetData($typUUID,1,0x626FC520)
    DLLStructSetData($typUUID,2,0xA41E)
    DLLStructSetData($typUUID,3,0x11CF)
    DLLStructSetData($typUUID,4,0xA7,1)
    DLLStructSetData($typUUID,4,0x31,2)
    DLLStructSetData($typUUID,4,0x0,3)
    DLLStructSetData($typUUID,4,0xA0,4)
    DLLStructSetData($typUUID,4,0xC9,5)
    DLLStructSetData($typUUID,4,0x8,6)
    DLLStructSetData($typUUID,4,0x26,7)
    DLLStructSetData($typUUID,4,0x37,8)

    $aRet = DllCall("oleacc.dll", "int", "ObjectFromLresult", "int", $lResult, _
            "ptr", DLLStructGetPtr($typUUID), "int", 0, "idispatch_ptr", "")
    If @error Then Return SetError(@error,@extended,0)

    If Not IsObj($aRet[4]) Then Return SetError(1,@extended,0)

    $oIE = $aRet[4].Script()
; $oIE is now a valid IDispatch object
;Return $oIE.document.parentwindow
    Return $oIE
EndFunc

Func _RegisterWindowMessage($sMsg)
    Local $aRet = DllCall("user32.dll", "int", "RegisterWindowMessage", "str", $sMsg)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aRet[0]
EndFunc; _RegisterWindowMessage()

Func _SendMessageTimeout($hWnd, $msg, $wParam, $lParam, $nFlags, $nTimeout, ByRef $vOut, $r = 0, $t1 = "int", $t2 = "int")
    Local $aRet = DllCall("user32.dll", "long", "SendMessageTimeout", "hwnd", $hWnd, "int", $msg, $t1, $wParam, $t2, $lParam, "int", $nFlags, "int", $nTimeout, "int_ptr", "")
    If @error Then
        $vOut = 0
        Return SetError(@error, @extended, 0)
    EndIf
    $vOut = $aRet[7]
    If $r >= 0 And $r <= 4 Then Return $aRet[$r]
    Return $aRet
EndFunc; _SendMessageTimeout()

Whenever I try a method that accesses the DOM, I get the "Return $o_IE.document^ ERROR" as if the $o_IE had no document!

I'm running the latest Autoit3 (3.2.4.9)

Any ideas on how to automate this dialog? I would prefer to stay away from mouse clicks and coordinates, as in my experience, automating DOM elements using IE.au3 is much more reliable.

I have extracted from the CD and attached the CDsetup.exe along with the files needed to display the dialog, as this should be enough to do some testing.

It can be downloaded from here

Any help, concern, comment, recommendation is much appreciated as I'm farily new to AutoIT and there's probably something that I'm missing here!

Regards,

TunaSalad

Edited by TunaSalad
Why crabs don't give money to charity..... because they are shell-fish!! PS: Don't be a crab and share your scripts with the community! ;-)
Link to comment
Share on other sites

Does this get you some HTML to work with?

#include <IE.au3>

_IEErrorHandlerRegister()

$h_Win = WinGetHandle("McAfee CDSetup")
WinActivate($h_Win)
$h_Ctrl = ControlGetHandle($h_Win, "", "[Class:Internet Explorer_Server]")
$o_IE = _ObjGetFromHWND($h_Ctrl)

If IsObj($o_IE) Then
    ConsoleWrite("Got the IE Object" & @CRLF)
    $sHTML = _IEBodyReadHTML($o_IE)
    $hFile = FileOpen("McAfee_HTML.txt", 2)
    FileWrite($hFile, $sHTML)
    FileClose($hFile)
    Run("notepad.exe McAfee_HTML.txt")
Else
    ConsoleWrite("Failed to get IE Object" & @CRLF)
EndIf

:whistle:

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
Link to comment
Share on other sites

BTW, Larry's _ObjGetFromHWND is incorporated in _IEAttach "embedded" like:

$oIE = _IEAttach ("A Window Title", "embedded")

Dale

Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y

Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Link to comment
Share on other sites

  • 1 year later...

BTW, Larry's _ObjGetFromHWND is incorporated in _IEAttach "embedded" like:

$oIE = _IEAttach ("A Window Title", "embedded")

Dale

Hi Guys,

Have run into a similar problem. I need to access an embedded instance of internet explorer. I tried using the _IEAttach method passing the Window name and "embedded" as the mode but no success with that. So i broke up the calls to internal functions of IE.au3 and found that a call to function DllCall is returning an error. Here's what my code looks like:

$handle = WinGetHandle("Window Name")

_IEErrorHandlerRegister()

WinActivate($handle)

$h_Ctrl = ControlGetHandle($handle, "", "[Class:Internet Explorer_Server]")

$o_IE = ___IEControlGetObjFromHWND($h_Ctrl)

MsgBox(0, "Error Status", @error)

Inside the ___IEControlGetObjFromHWND function:

Func __IEControlGetObjFromHWND(ByRef $hWin)

DllCall("ole32.dll", "int", "CoInitialize", "ptr", 0)

Local Const $WM_HTML_GETOBJECT = __IERegisterWindowMessage("WM_HTML_GETOBJECT")

Local Const $SMTO_ABORTIFHUNG = 0x0002

Local $lResult, $typUUID, $aRet, $oIE

__IESendMessageTimeout($hWin, $WM_HTML_GETOBJECT, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lResult)

MsgBox(0, "Result", $lResult)

$typUUID = DllStructCreate("int;short;short;byte[8]")

DllStructSetData($typUUID, 1, 0x626FC520)

DllStructSetData($typUUID, 2, 0xA41E)

DllStructSetData($typUUID, 3, 0x11CF)

DllStructSetData($typUUID, 4, 0xA7, 1)

DllStructSetData($typUUID, 4, 0x31, 2)

DllStructSetData($typUUID, 4, 0x0, 3)

DllStructSetData($typUUID, 4, 0xA0, 4)

DllStructSetData($typUUID, 4, 0xC9, 5)

DllStructSetData($typUUID, 4, 0x8, 6)

DllStructSetData($typUUID, 4, 0x26, 7)

DllStructSetData($typUUID, 4, 0x37, 8)

$aRet = DllCall("oleacc.dll", "int", "ObjectFromLresult", "int", $lResult, "ptr", DllStructGetPtr($typUUID), _

"int", 0, "idispatch_ptr", "")

MsgBox(0, "Error", @error)

If IsObj($aRet[4]) Then

$oIE = $aRet[4].Script ()

; $oIE is now a valid IDispatch object

Return $oIE.document.parentwindow

Else

SetError(1)

Return 0

EndIf

EndFunc

After the DllCall("oleacc.dll", "int", "ObjectFromLresult", "int", $lResult, "ptr", DllStructGetPtr($typUUID), "int", 0, "idispatch_ptr", ""), i placed a msgbox to get the error which as it turns out is 2. According to the help file, @error = 2 unknown "return type".

So whats going wrong here? I am actually trying to get control of the embedded browser so that I can navigate around and get/post data.

Any help in this regard will be highly appreciated.

Thanks.

Link to comment
Share on other sites

  • 3 years later...

I've run into this same error. I'm trying to see if I can access the a Windows 7 Sidebar Gadget's HTML etc. My problem is that any time I try to access the IDispatch object's properties, I get an "Access is Denied" error. If anyone can help, I would be extremely grateful! Here's my code:

#include <IE.au3>
_IEErrorHandlerRegister()
Func ___IEControlGetObjFromHWND(ByRef $hWin)
DllCall("ole32.dll", "long", "CoInitialize", "ptr", 0)
If @error Then Return SetError(2, @error, 0)
Local Const $WM_HTML_GETOBJECT = __IERegisterWindowMessage("WM_HTML_GETOBJECT")
Local Const $SMTO_ABORTIFHUNG = 0x0002
Local $lResult
__IESendMessageTimeout($hWin, $WM_HTML_GETOBJECT, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lResult)
Local $typUUID = DllStructCreate("int;short;short;byte[8]")
DllStructSetData($typUUID, 1, 0x626FC520)
DllStructSetData($typUUID, 2, 0xA41E)
DllStructSetData($typUUID, 3, 0x11CF)
DllStructSetData($typUUID, 4, 0xA7, 1)
DllStructSetData($typUUID, 4, 0x31, 2)
DllStructSetData($typUUID, 4, 0x0, 3)
DllStructSetData($typUUID, 4, 0xA0, 4)
DllStructSetData($typUUID, 4, 0xC9, 5)
DllStructSetData($typUUID, 4, 0x8, 6)
DllStructSetData($typUUID, 4, 0x26, 7)
DllStructSetData($typUUID, 4, 0x37, 8)
Local $aRet = DllCall("oleacc.dll", "long", "ObjectFromLresult", "lresult", $lResult, "ptr", DllStructGetPtr($typUUID), _
   "wparam", 0, "idispatch*", 0)
If @error Then Return SetError(3, @error, 0)
If IsObj($aRet[4]) Then
  Local $oIE = $aRet[4] .Script()
  ;removed $oIE.contentwindow.document stuff, caused an error...
  Return $oIE
Else
  Return SetError(1, $aRet[0], 0)
EndIf
EndFunc
$hWnd = WinGetHandle("[CLASS:SideBar_HTMLHostWindow; INSTANCE: 1]") ;Gets the window of the control
$h_control = ControlGetHandle($hWnd, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]") ;Gets the embedded Internet Explorer control
$o = ___IEControlGetObjFromHWND($h_control) ;Converts to IDispatch
ConsoleWrite(ObjName($o) & @CRLF) ;Writes 'DispHTMLWindow2'
$o ;any attempts to access $o's properties result in a "Access is Denied" error
Edited by motionman95
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...