wuruoyu Posted November 11, 2016 Posted November 11, 2016 (edited) Press button to go to the website with _IECreate(), if IE window is closed before website is loaded, the button is no longer working. In another script, I am able to use OBJEvent to monitor if IE window is abruptly closed, then restart the whole script, but in ideal scenario I don't want to restart the whole script. Thank you in advance for any help or suggestion To reproduce: 1. Click on "Open Website" button, wait for IE window to open and quickly click the red "X" button to close the IE window before the website finishes loading. 2. "Open Website" button is no longer working. expandcollapse popup#NoTrayIcon #include <StaticConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiButton.au3> #include <EditConstants.au3> #include <IE.au3> Opt("GUIOnEventMode", 1) ;_IEErrorHandlerRegister(_IEErrorFunc) Global $OpenWebsiteButton, $openWebsiteButtonFlg, $IEHWND _main() Func _IEErrorFunc($oError) ConsoleWrite(@ScriptFullPath & " (" & $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 ;==>_IEErrorFunc Func _main() $main = GUICreate("main", 143, 63, -1, -1, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_exit") $OpenWebsiteButton = GUICtrlCreateButton("Open Website", 20, 20, 100, 20, -1, -1) GUICtrlSetOnEvent(-1, "_openWebsiteButton") GUISetState(@SW_SHOW, $main) While 1 Select Case $openWebsiteButtonFlg = True _openWebsiteButtonAction() $openWebsiteButtonFlg = False EndSelect Sleep(100) WEnd EndFunc ;==>_main Func _exit() Exit EndFunc ;==>_exit Func _openWebsiteButton() Switch @GUI_CtrlId Case $OpenWebsiteButton $openWebsiteButtonFlg = True EndSwitch EndFunc Func _openWebsiteButtonAction() If ObjName($IEHWND) = "IWebBrowser2" Then _IEQuit($IEHWND) ;If @error Then Return SetError(@error, @extended, -1) EndIf Local $url = "https://www.autoitscript.com/site/" _IECreate($url, 0, 1, 0) ;If @error Then Return SetError(@error, @extended, -1) Local $websiteTimer = TimerInit() Do While 1 $aWinList = WinList("[CLASS:IEFrame]") For $i = 1 To $aWinList[0][0] If BitAND(WinGetState($aWinList[$i][1]), 2) And StringInStr(WinGetText($aWinList[$i][1]), $url) Then $IEHWND = _IEAttach($aWinList[$i][1], "hwnd") ;If @error Then Return SetError(@error, @extended, -1) ExitLoop 3 EndIf Next WEnd Until TimerDiff($websiteTimer) > 6000 EndFunc Edited November 11, 2016 by wuruoyu
czardas Posted November 11, 2016 Posted November 11, 2016 (edited) This seems to work, but you will have to test it. Func _openWebsiteButtonAction() If ObjName($IEHWND) = "IWebBrowser2" Then _IEQuit($IEHWND) ;If @error Then Return SetError(@error, @extended, -1) EndIf Local $url = "https://www.autoitscript.com/site/" _IECreate($url, 0, 1, 0) ;If @error Then Return SetError(@error, @extended, -1) Local $websiteTimer = TimerInit() Do While 1 $aWinList = WinList("[CLASS:IEFrame]") For $i = 1 To $aWinList[0][0] If BitAND(WinGetState($aWinList[$i][1]), 2) And StringInStr(WinGetText($aWinList[$i][1]), $url) Then $IEHWND = _IEAttach($aWinList[$i][1], "hwnd") ;If @error Then Return SetError(@error, @extended, -1) ExitLoop 3 EndIf Next WEnd Until TimerDiff($websiteTimer) > 6000 $openWebsiteButtonFlg = False ; <<<<<<<<<<< ADDED THIS LINE <<<<<<<<<<<< EndFunc Edit I'm not sure why you need the function _openWebsiteButton(). Oops, sorry. Now I understand the problem. I was too slow in clicking the red x. Edited November 11, 2016 by czardas operator64 ArrayWorkshop
wuruoyu Posted November 11, 2016 Author Posted November 11, 2016 Thank you czardas for the quick reply. I did try the same thing earlier and just now, it's still not working. P.S to successfully reproduce the problem, I have to close the IE window really really fast (right when it's launched).
czardas Posted November 11, 2016 Posted November 11, 2016 (edited) I must admit that I find this a bit hard to understand. I tend to use message loop mode and not so much GUICtrlSetOnEvent(). Anyway I have tried a few things, but I'm not entirely satisfied with what I tried. This seems to be my best attempt, without completely rewriting your code. I don't yet know why it behaves the way it does. If it works, this not a fix: it's a patch. expandcollapse popup#NoTrayIcon #include <StaticConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiButton.au3> #include <EditConstants.au3> #include <IE.au3> Opt("GUIOnEventMode", 1) ;_IEErrorHandlerRegister(_IEErrorFunc) Global $OpenWebsiteButton, $openWebsiteButtonFlg = False, $IEHWND, $IE_TITLE = False _main() Func _IEErrorFunc($oError) ConsoleWrite(@ScriptFullPath & " (" & $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 ;==>_IEErrorFunc Func _main() $main = GUICreate("main", 143, 63, -1, -1, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_exit") $OpenWebsiteButton = GUICtrlCreateButton("Open Website", 20, 20, 100, 20, -1, -1) GUICtrlSetOnEvent(-1, "_openWebsiteButton") GUISetState(@SW_SHOW, $main) While 1 Select Case $openWebsiteButtonFlg = True _openWebsiteButtonAction() $openWebsiteButtonFlg = False EndSelect If Not WinExists($IE_TITLE) Then $openWebsiteButtonFlg = False ; this is strange Sleep(100) WEnd EndFunc ;==>_main Func _exit() Exit EndFunc ;==>_exit Func _openWebsiteButton() Switch @GUI_CtrlId Case $OpenWebsiteButton $openWebsiteButtonFlg = True EndSwitch EndFunc Func _openWebsiteButtonAction() If ObjName($IEHWND) = "IWebBrowser2" Then _IEQuit($IEHWND) ;If @error Then Return SetError(@error, @extended, -1) EndIf Local $url = "https://www.autoitscript.com/site/" _IECreate($url, 0, 1, 0) ;If @error Then Return SetError(@error, @extended, -1) Local $websiteTimer = TimerInit() Do While 1 $aWinList = WinList("[CLASS:IEFrame]") For $i = 1 To $aWinList[0][0] If BitAND(WinGetState($aWinList[$i][1]), 2) And StringInStr(WinGetText($aWinList[$i][1]), $url) Then $IEHWND = _IEAttach($aWinList[$i][1], "hwnd") $IE_TITLE = WinGetTitle($aWinList[$i][1]) ;If @error Then Return SetError(@error, @extended, -1) ExitLoop 3 EndIf Next WEnd Until TimerDiff($websiteTimer) > 6000 EndFunc Perhaps some of the error code could be useful. I don't know why it is commented out. Actually this may be a big part of the problem: errors should be checked. Edited November 11, 2016 by czardas operator64 ArrayWorkshop
wuruoyu Posted November 11, 2016 Author Posted November 11, 2016 (edited) Thank you again czardas! Unfortunately, I can still make the button to stop working by closing the IE window quickly. Further testing, I think it might have something to do with while loop, if I close the window quick enough to stop the button from functioning, the process is constantly using 25% of CPU. If I remove the while loop, it appears to be working fine even if IE window is closed quickly. But I have to use this while loop in order to use _IEAttach because the website that I am accessing only works with following method. While 1 $aWinList = WinList("[CLASS:IEFrame]") For $i = 1 To $aWinList[0][0] If BitAND(WinGetState($aWinList[$i][1]), 2) And StringInStr(WinGetText($aWinList[$i][1]), $url) Then $IEHWND = _IEAttach($aWinList[$i][1], "hwnd") $IE_TITLE = WinGetTitle($aWinList[$i][1]) ;If @error Then Return SetError(@error, @extended, -1) ExitLoop 3 EndIf Next WEnd Edited November 11, 2016 by wuruoyu
czardas Posted November 11, 2016 Posted November 11, 2016 You must have faster fingers than me! It's strange because it seems to work sometimes, and at other times not. For some reason it seems to work if you treat it carefully. If I instantly press Alt+F4 to close the window before it has fully loaded, the script crashes and I get this in the console of SciTE: "C:\Program Files\AutoIt3\Include\IE.au3" (2167) : ==> The requested action with this object has failed.: Return SetError($_IESTATUS_Success, 0, HWnd($oObject.HWnd())) Return SetError($_IESTATUS_Success, 0, HWnd($oObject^ ERROR ->22:56:48 AutoIt3.exe ended.rc:1 This is most likely because there is no error handling in your code. I'm a bit tired to figure it out right now. operator64 ArrayWorkshop
wuruoyu Posted November 12, 2016 Author Posted November 12, 2016 Thank you for all your testing czardas. I did get the same error once as well. But it's same result with IE error handler on or off.
czardas Posted November 12, 2016 Posted November 12, 2016 It could also be an AutoIt bug or even a Windows bug. I have a similar problem where the right and left arrow keys simply stop working after spamming the keyboard for a while, but it's hard to reproduce the behaviour consistently. The code also uses On Event message handling. operator64 ArrayWorkshop
czardas Posted November 12, 2016 Posted November 12, 2016 (edited) This is my final attempt. I removed the loops from _openWebsiteAction() along with some other changes. The crash I mentioned, indicates that there is a problem with the IE UDF and needs further investigation. expandcollapse popup#NoTrayIcon #include <StaticConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiButton.au3> #include <EditConstants.au3> #include <IE.au3> Opt("GUIOnEventMode", 1) ;_IEErrorHandlerRegister(_IEErrorFunc) Global $OpenWebsiteButton, $IEHWND ; ,$openWebsiteButtonFlg _main() Func _IEErrorFunc($oError) ConsoleWrite(@ScriptFullPath & " (" & $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 ;==>_IEErrorFunc Func _main() $main = GUICreate("main", 143, 63, -1, -1, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_exit") $OpenWebsiteButton = GUICtrlCreateButton("Open Website", 20, 20, 100, 20, -1, -1) GUICtrlSetOnEvent(-1, "_openWebsiteButton") GUISetState(@SW_SHOW, $main) While 1 Sleep(10) WEnd EndFunc ;==>_main Func _exit() Exit EndFunc ;==>_exit Func _openWebsiteButton() Switch @GUI_CtrlId Case $OpenWebsiteButton _openWebsiteButtonAction() EndSwitch ; $openWebsiteButtonFlg = False EndFunc Func _openWebsiteButtonAction() If ObjName($IEHWND) = "IWebBrowser2" Then _IEQuit($IEHWND) If @error Then Return SetError(@error, @extended, -1) EndIf Local $url = "https://www.autoitscript.com/site/" _IECreate($url, 0, 1, 0) If @error Then Return SetError(@error, @extended, -1) ;Local $websiteTimer = TimerInit() ;Do ; While 1 $aWinList = WinList("[CLASS:IEFrame]") For $i = 1 To $aWinList[0][0] If BitAND(WinGetState($aWinList[$i][1]), 2) And StringInStr(WinGetText($aWinList[$i][1]), $url) Then $IEHWND = _IEAttach($aWinList[$i][1], "hwnd") If @error Then Return SetError(@error, @extended, -1) ExitLoop ;3 EndIf Next ; WEnd ;Until TimerDiff($websiteTimer) > 6000 EndFunc When the window was closed too quickly, you were getting stuck in the while loop because the window could no longer be found. I think it's that simple. Edited November 12, 2016 by czardas operator64 ArrayWorkshop
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