Ximorro Posted May 19, 2023 Posted May 19, 2023 Good day everybody, I just upgraded Autoit from version 3.3.14.5 to 3.3.16.1 and programs that use Shell.Explorer.2 COM Object are not working anymore. Nothing else has changed in the system, the program failed just after updating AutoIt. The original program is bigger but I can show the issue for instance in this small program to write in the body of the html document: expandcollapse popup#include <GuiConstants.au3> Global $GUI_IE, $btnCerrar, $oIE, $ancho = 200, $alto = 150 Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") #forceref $oErrorHandler $GUI_IE = GUICreate("Shell Explorer", $ancho,$alto, -1,-1, BitOr($WS_CAPTION, $WS_POPUP, $WS_CLIPCHILDREN)) $btnCerrar = GUICtrlCreateButton("Close", ($ancho-60)/2,$alto-30, 60,24) $oIE = ObjCreate("Shell.Explorer.2") GUICtrlCreateObj($oIE, 10,10, $ancho-20,$alto-46) $oIE.navigate("about:blank") ;$oIE.navigate("https://www.example.com") $oIE.document.body.innerHTML = "<p>HELLO</p>" While $oIE.busy Sleep(50) WEnd GUISetState(@SW_SHOW, $GUI_IE) While 1 Switch GUIGetMsg() Case $btnCerrar, $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($GUI_IE) $oIE=0 Func _ErrFunc($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.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 ;==>_ErrFunc _ErrFunc() is showing error 0x00000003: "Object Invoke failed" in the line with [$oIE.document.body.innerHTML = "<p>HELLO</p>"] To narrow the problem source I have split the access to the property with: Global $doc = $oIE.Document ConsoleWrite("Document is Object: " & IsObj($doc) & @CRLF) ;Returns 1 (object ok) Global $body = $doc.body ConsoleWrite("body is Object: " & IsObj($body) & @CRLF) ;Returns 0 (not object!) $body.innerHTML = "<p>HELLO</p>" ;Obviously fails since $body is not an object $oiE.Document works and I can invoke other methods on $doc. But $doc.body doesn´t return an object (Error: Object Invoke failed). Please notice: the problem is not starting with "about:blank", you can navigate to a full page (like "http://www.example.com" or "https://www.autoitscript.com") and body property is not accessible either. The problem isn't that I try to modify it with innerHTML, just trying to read the body already fails. All this worked without changes in v3.3.14.5. I know in the last version there have been some changes in COM error handling but I don't think I have to do something different to avoid the error in this version. Am I doing anything wrong? Thank you.
Solution Gianni Posted May 19, 2023 Solution Posted May 19, 2023 Hi @Ximorro, shouldn't you place the innerHTML setting after the $oIE "busy" status check? however I think checking the "busy" status is not enough. try with this 2 lines: Do Sleep(50) Until ($oIE.readyState = 'complete' Or $oIE.readyState = 4) $oIE.document.body.innerHTML = "<p>HELLO</p>" instead of $oIE.document.body.innerHTML = "<p>HELLO</p>" While $oIE.busy Sleep(50) WEnd Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
Ximorro Posted May 19, 2023 Author Posted May 19, 2023 Hi Gianni! Well, when creating a blank page using about:blank that's not necessary, at least in my tests the body is always ready immediately. That's how I use it so I left the code like that. (I use this to show small formatted help windows in my programs) You are right that when loading a web page, like with $oIE.navigate("https://www.example.com"), it's advisable to wait for it to be ready before modifying it. I already tried putting the waiting loop before accessing the body and it didn´t work but I didn't think about "readyState", let me test... IT WORKS! So the trick here is to use "$oIE.readyState" instead of "$oIE.busy". I misunderstood then this method because the documentatio says: Busy property: Gets a value that indicates whether the object is engaged in a navigation or downloading operation. So I thought that when not busy all was clear. So the explanation must be Autoit v3.3.16.1 needs more time to get the page ready and checking for busy (before accessing, not like in my example) is not enough because it can be "not busy" but still not completely ready. One question, where can I read info about those string status for readyState like 'complete' you use? In MSN documentation I only see reference to READYSTATE enumeration so only info about integer values (and the constants for C that we cannot use in AutoIt directly) Thanks Gianni! I'll check in my more convoluted programs but clearly checking for readyState instead of busy fixes these examples so I'm giving you the solution mark. Very appreciated, I was getting nuts, checking in different OS, x64 or x32, reinstalling v.3.3.14.5 (where it worked again)...
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