Sign in to follow this  
Followers 0
Jewtus

Issue with IE crashing on element select

13 posts in this topic

#1 ·  Posted (edited)

I have a script that automatically selects a radio button on a page. Sometimes, it doesn't actually select the radio button, so I set up a redundancy to make sure the button is checked. I am having some trouble with it though. The script will start running and work for about 14 or 15 times and then the program crashes.

This is my code:

$oAutoCloseForm = _IEFormGetObjByName($oIE, "unableToRespondForm")
    While _IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",-1,"byValue") = False
        _IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",1,"byValue")
        If @error Then
            ExitLoop
        Endif
    Wend



This is the console readout from SCiTE:

 

--> IE.au3 T3.0-2 Warning from function _IEFormElementRadioSelect, $_IESTATUS_NoMatch
--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function _IEFormElementRadioSelect, $_IESTATUS_NoMatch
--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
!>07:23:35 AutoIt3.exe ended.rc:-1073741819

 

I have no idea why its failing (or why it sometimes doesn't find a match). The script does operate fine for a few attempts, then it just crashes out. Anyone have any suggestions on what I can do to prevent the crash (or suggestions on how to capture what is causing the crash so I can handle it)?

Here is the windows crash log:

 

Problem signature:

Problem Event Name: APPCRASH

Application Name: autoit3.exe

Application Version: 3.3.13.19

Application Timestamp: 53fa0936

Fault Module Name: OLEAUT32.dll

Fault Module Version: 6.1.7601.18640

Fault Module Timestamp: 5441c30c

Exception Code: c0000005

Exception Offset: 0002120f

OS Version: 6.1.7601.2.1.0.256.48

Locale ID: 1033

Additional Information 1: 0a9e

Additional Information 2: 0a9e372d3b4ad19135b953a78882e789

Additional Information 3: 0a9e

Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

Edited by Jewtus

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Try this to prevent the crash:

$oAutoCloseForm = Execute('_IEFormGetObjByName($oIE, ""unableToRespondForm"")')
    While Execute('_IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",-1,"byValue")') = False
        Execute('_IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",1,"byValue")')
        If @error Then
            ExitLoop
        Endif
    Wend

Edit:

I should state, this is a bandaid.

The real problem I can see is upon success, your object may not exist anymore, if this is not the case then you're fine.  If it may be the case, then you need to put more code checking in the loop (as well as a Sleep(10) at least after your EndIf).

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

you could try something like this to be sure that the form "unableToRespondForm" is ready before you go ahead with your script:

Do
    $oAutoCloseForm = _IEFormGetObjByName($oIE, "unableToRespondForm")
Until IsObj($oAutoCloseForm)
;
While _IEFormElementRadioSelect($oAutoCloseForm, "NO_ACCOUNTS", "reason", -1, "byValue") = False
    _IEFormElementRadioSelect($oAutoCloseForm, "NO_ACCOUNTS", "reason", 1, "byValue")
    If @error Then
        ExitLoop
    EndIf
WEnd

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Try this to prevent the crash:

$oAutoCloseForm = Execute('_IEFormGetObjByName($oIE, ""unableToRespondForm"")')
    While Execute('_IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",-1,"byValue")') = False
        Execute('_IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",1,"byValue")')
        If @error Then
            ExitLoop
        Endif
    Wend

Edit:

I should state, this is a bandaid.

The real problem I can see is upon success, your object may not exist anymore, if this is not the case then you're fine.  If it may be the case, then you need to put more code checking in the loop (as well as a Sleep(10) at least after your EndIf).

OK, So I tried this and it seems to work (Needed to remove one set of quotes) but it crashes after about 10 tries) I put the sleep delay in as well.

 

you could try something like this to be sure that the form "unableToRespondForm" is ready before you go ahead with your script:

Do
    $oAutoCloseForm = _IEFormGetObjByName($oIE, "unableToRespondForm")
Until IsObj($oAutoCloseForm)
;
While _IEFormElementRadioSelect($oAutoCloseForm, "NO_ACCOUNTS", "reason", -1, "byValue") = False
    _IEFormElementRadioSelect($oAutoCloseForm, "NO_ACCOUNTS", "reason", 1, "byValue")
    If @error Then
        ExitLoop
    EndIf
WEnd

I also tried this, but it doesn't work at all. The console out says no match for the IEformGetObj and never exits the do loop.

Should I just take all the IE functions I use and put them into my local script to see exactly why its failing? Anyone else have suggestions?

Edited by Jewtus

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Makes sense that mine would crash, it doesn't do anything different than yours did.

I must have been half asleep, all I did was wrap the functions themselves.

If this fails, then it's somewhere else in your code.  But keep in mind, if the radio is never found, then it will stick in this loop forever.

Local $oItems = 0

While 1
    ; validate that the object exists
    ; if it doesn't, continueloop until it does
    $oItems = Execute("$oAutoCloseForm.elements('reason')")
    If Not IsObj($oItems) Then
        Sleep(10) ; cpu rest
        ContinueLoop
    EndIf

    ; byvalue
    For $oItem In $oItems
        If String(Execute("$oItem.type")) = "radio" And String(Execute("$oItem.value")) = "NO_ACCOUNTS" Then
            If Execute('$oItem.checked') Then ExitLoop ; it's already checked, move on
            Execute("$oItem.checked") = True
            Execute('$oItem.fireEvent("onChange")')
            Execute('$oItem.fireEvent("OnClick")')
            ; found, we're done
            ExitLoop
        EndIf
    Next
WEnd

Good luck.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Throw one of these at the top of your script:

_IEErrorHandlerRegister

The IE functions are prone to perform actions on browsers, when the DOM isn't fully loaded (crashes the script).

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Makes sense that mine would crash, it doesn't do anything different than yours did.

I must have been half asleep, all I did was wrap the functions themselves.

If this fails, then it's somewhere else in your code.  But keep in mind, if the radio is never found, then it will stick in this loop forever.

Local $oItems = 0

While 1
    ; validate that the object exists
    ; if it doesn't, continueloop until it does
    $oItems = Execute("$oAutoCloseForm.elements('reason')")
    If Not IsObj($oItems) Then
        Sleep(10) ; cpu rest
        ContinueLoop
    EndIf

    ; byvalue
    For $oItem In $oItems
        If String(Execute("$oItem.type")) = "radio" And String(Execute("$oItem.value")) = "NO_ACCOUNTS" Then
            If Execute('$oItem.checked') Then ExitLoop ; it's already checked, move on
            Execute("$oItem.checked") = True
            Execute('$oItem.fireEvent("onChange")')
            Execute('$oItem.fireEvent("OnClick")')
            ; found, we're done
            ExitLoop
        EndIf
    Next
WEnd

Good luck.

When I tried this, I get an error on the Execute("$oItem.checked") = True line. SciTE says "error: Statement cannot be just an expression"

 

@Jdelany

I also am not sure what you mean when you say to throw one of those at the top of my script. I tried to look up the syntax and it looks like that function was removed in 3.3.10 (December 23 2013)

EDIT: I just put _IEErrorHandlerRegister() at the top of my func and it output:

--> IE.au3 T3.0-2 Warning from function _IEFormElementRadioSelect, $_IESTATUS_NoMatch

--> COM Error encountered in DataExtract&Closeout.au3 (1318) :

----> $IEComErrorNumber           = 0x80070057 (-2147024809)

----> $IEComErrorWinDescription             = The parameter is incorrect.

----> $IEComErrorDescription     =

----> $IEComErrorSource              =

----> $IEComErrorHelpFile            =

----> $IEComErrorHelpContext                   =

----> $IEComErrorLastDllError     = 0

----> $IEComErrorRetcode           = 0x00000000

I was also able to get the script to work with this in the beginning:

 

Do
    $oAutoCloseForm = _IEFormGetObjByName($oIE, "unableToRespondForm")
Until IsObj($oAutoCloseForm)
Edited by Jewtus

Share this post


Link to post
Share on other sites

Replace:

Execute("$oItem.checked") = True
 
With:
Execute("$oItem.checked = True")

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

That seems to no longer kick up an error, but it doesn't actually tick the box... I'm going to update what I've got working so far.

Share this post


Link to post
Share on other sites

I'm using an old version, but yes, any error handler will work.


IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Func AutoClose($aClose)
    _IEErrorHandlerRegister()
    _IENavigate($oIE, $URL & $aClose)
    sleep(200)
    $oTable = _IETableGetCollection($oIE)
    $iNumTables = @extended
    $oMeta = _IETableGetCollection($oIE, 0)
    $aMeta = _IETableWriteToArray($oMeta, True)
    If not @error Then
        If $iNumTables = 6 Then
            Do
                $oAutoCloseForm = _IEFormGetObjByName($oIE, "unableToRespondForm")
            Until IsObj($oAutoCloseForm)
            While _IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",-1,"byValue") = False
                _IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",1,"byValue")
                If @error Then
                    ExitLoop
                Else
                   sleep(200)
                    _IEFormSubmit($oAutoCloseForm)             
                EndIf
            ExitLoop
            WEnd
        EndIf
    EndIf
EndFunc

Here is what I've gotten to work so far, but it still crashes, but it seems to run for quite a bit longer (ran for almost an hour and a half before crashing this time)

Edited by Jewtus

Share this post


Link to post
Share on other sites

Try to put your Do...Until inside your the top of your While:

Something like:

While 1
                Do
                    $oAutoCloseForm = _IEFormGetObjByName($oIE, "unableToRespondForm")
                    Sleep(10)
                Until IsObj($oAutoCloseForm)
                If Not _IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",-1,"byValue") Then ContinueLoop
                
                _IEFormElementRadioSelect($oAutoCloseForm,"NO_ACCOUNTS","reason",1,"byValue")
                If @error Then ExitLoop
                Sleep(200)
                _IEFormSubmit($oAutoCloseForm)      
                ExitLoop
            WEnd

This way, if $oAutoCloseForm goes out of scope, it will go back to finding it.

This is really the only other suggestion I could even remotely offer without being able to play with the site area myself and trap the event errors.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

I tried that one and it doesn't select the radio button.

I think I'm going to just customize the script and not use a UDF. 

At least I know exactly what function is failing now.

Thanks for the suggestions everyone.

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  
Followers 0