Sign in to follow this  
Followers 0
lgodfrey

ObjEvent runtime error

14 posts in this topic

My first time using Object Events. I get a WXP error pop up that "Autoit3.exe has encountered a problem and has to close, sorr for the inconvenience" when the second dim line is executed (no error if I comment it out)

opt("MustDeclareVars", 1)     ;0=no, 1=require pre-declare      *************not default
Dim $o_HTTP = ObjCreate ("winhttp.winhttprequest.5.1")
Dim $SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")
Exit
I can't identifiy anything wrong, help please.

Larry


I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites



catch the COM errors to figure out what's the problem. See help file index: Obj/COM Reference. Read section: COM Error Handling.

Cheers

Kurt


__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Share this post


Link to post
Share on other sites

My first time using Object Events. I get a WXP error pop up that "Autoit3.exe has encountered a problem and has to close, sorr for the inconvenience" when the second dim line is executed (no error if I comment it out) 

opt("MustDeclareVars", 1)    ;0=no, 1=require pre-declare       *************not default
Dim $o_HTTP = ObjCreate ("winhttp.winhttprequest.5.1")
Dim $SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")
Exit
I can't identifiy anything wrong, help please.

Larry

<{POST_SNAPBACK}>

You posted in the "v3 AutoItX Forum" which pertains to "AutoItX3.dll"

Are you talking about "v3 AutoItX" or the latest beta of "AutoIt v3" ?

Share this post


Link to post
Share on other sites

catch the COM errors to figure out what's the problem. See help file index: Obj/COM Reference. Read section: COM Error Handling.

Cheers

Kurt

<{POST_SNAPBACK}>

Forgot to mention I tried that before I started reducing the code to try to isolate the errror. Here it is with error trapping added back, both for autoit and the object. It still bombs at the $SinkOject dim statement. Maybe I did something wrong with the error handling?
opt("MustDeclareVars", 1)     ;0=no, 1=require pre-declare      *************not default
Dim $o_HTTP = ObjCreate ("winhttp.winhttprequest.5.1"),$oMyError,$DLError,$HexNumber
Dim $SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler 
Exit
Func HTTPEvent_onerror($ErrNo, $ErrDesc)
    SetError(1)
    $DLError = 1
    MsgBox(262144, 'Debug line ~35', 'Selection:' & @LF & '$ErrNo' & @LF & @LF & 'Return:' & @LF & $ErrNo & @LF & $ErrDesc & @LF & '@Error:' & @LF & @error & @LF & @LF & '@Extended:' & @LF & @extended);### Debug MSGBOX
EndFunc  ;==>HTTPEvent_onerror
; This is my custom error handler 
Func MyErrFunc() 
   $HexNumber=hex($oMyError.number,8) 
   Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _
               "Number is: " & $HexNumber & @CRLF & _
               "Windescription is: " & $oMyError.windescription ) 

   SetError(1); something to check for when this function returns 
Endfunc

The error does seem to happen at the dim $sinkobject line, and the syntax is fairly straight forward so I do not see an error there. If I debug to msg box the $o_HTTP result, it gives @error=0 and blank for $o_HTTP. IsObj on $0_HTTP returns 1, and I coppied this line from a working code anyway.

As bshoenhair pointed out I mixed up AutoIT X posting with beta posting, I should have put this into Developers section I guess. I have no idea what the error handling subroutine should be for this one!

Larry


I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites

Forgot to mention I tried that before I started reducing the code to try to isolate the errror.  Here it is with error trapping added back, both for autoit and the object.  It still bombs at the $SinkOject dim statement.  Maybe I did something wrong with the error handling?

...

<{POST_SNAPBACK}>

Larry,

Could you try it without the 'MustDeclareVars' and the 'Dim' statements, just to test if it's still crashing?

I copy/pasted your script on my WinXPsp1 system and it didn't produce any error messages. Which Service pack level and which (exact) version of AutoIt3 are you currently using?

BTW: it's better to place the "AutoIt.Error" handler as 'high' as possible in your script. Preferably before any other Obj... function. Then it will also catch 'ObjEvent' errors (hopefully).

I have fixed some memory bugs in the latest version of the ObjEvent function. It will be included in the next AutoIt beta. But I doubt that has anything to do with this error.

Regards,

-Sven

Share this post


Link to post
Share on other sites

Larry,

Could you try it without the 'MustDeclareVars' and the 'Dim' statements, just to test if it's still crashing?

I copy/pasted your script on my WinXPsp1 system and it didn't produce any error messages.  Which Service pack level and which (exact) version of AutoIt3 are you currently using?

BTW: it's better to place the "AutoIt.Error" handler as 'high' as possible in your script. Preferably before any other Obj... function. Then it will also catch 'ObjEvent' errors (hopefully).

I have fixed some memory bugs in the latest version of the ObjEvent function. It will be included in the next AutoIt beta. But I doubt that has anything to do with this error.

Regards,

-Sven

<{POST_SNAPBACK}>

Thanks for looking at this. Here it is as requested, still gives same error. Moved "AutoIt.Error" to the top too, error is not trapped. I have AutoITv3.1.1 with V3.1.1.63(beta) Here's my WXP info:

OS Name Microsoft Windows XP Home Edition

Version 5.1.2600 Service Pack 2 Build 2600

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler 
$o_HTTP = ObjCreate ("winhttp.winhttprequest.5.1")
$SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")
Exit
Func HTTPEvent_onerror($ErrNo, $ErrDesc)
    SetError(1)
    $DLError = 1
    MsgBox(262144, 'Debug line ~35', 'Selection:' & @LF & '$ErrNo' & @LF & @LF & 'Return:' & @LF & $ErrNo & @LF & $ErrDesc & @LF & '@Error:' & @LF & @error & @LF & @LF & '@Extended:' & @LF & @extended);### Debug MSGBOX
EndFunc  ;==>HTTPEvent_onerror
; This is my custom error handler 
Func MyErrFunc() 
   $HexNumber=hex($oMyError.number,8) 
   Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _
               "Number is: " & $HexNumber & @CRLF & _
               "Windescription is: " & $oMyError.windescription ) 

   SetError(1); something to check for when this function returns 
Endfunc
Anything you see wrong?

Regards

Larry


I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites

Thanks for looking at this. Here it is as requested, still gives same error.  Moved  "AutoIt.Error" to the top too, error is not trapped.  I have AutoITv3.1.1 with V3.1.1.63(beta) Here's my WXP info:

OS Name Microsoft Windows XP Home Edition

Version 5.1.2600 Service Pack 2 Build 2600

.....

Anything you see wrong?

Regards

Larry

<{POST_SNAPBACK}>

Hello Larry,

There's absolutely nothing wrong with your code. However I can't get the same crash as on your system. I used the code without any modifications on the following systems:

Windows 2000pro SP4

Windows XP Pro SP1 (2600)

Windpws XP Pro SP2 (2600)

None of the systems produced a crash.

EDIT: While I was typing this message I finally got it crashing on a Windows 2003 Enterprise server with SP1. Exactly as you said. The mimimal code to reproduce it is similar to your first posting:

$o_HTTP = ObjCreate ("winhttp.winhttprequest.5.1")
$SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")

I don't know yet how to solve it (it's not wise doing debug jobs on an enterprise server), but at least I have a target to hunt for.

Regards,

-Sven

Share this post


Link to post
Share on other sites

Hello Larry,

There's absolutely nothing wrong with your code.  However I can't get the same crash as on your system.  I used the code without any modifications on the following systems:

Windows 2000pro SP4

Windows XP Pro SP1 (2600)

Windpws XP Pro SP2 (2600)

None of the systems produced a crash.

EDIT: While I was typing this message I finally got it crashing on a Windows 2003 Enterprise server with SP1.  Exactly as you said.  The mimimal code to reproduce it is similar to your first posting:

$o_HTTP = ObjCreate ("winhttp.winhttprequest.5.1")
$SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")

I don't know yet how to solve it (it's not wise doing debug jobs on an enterprise server), but at least I have a target to hunt for. 

Regards,

-Sven

<{POST_SNAPBACK}>

Thanks for looking at this.

My goal here is to create a substitute InetGet that has a timeout for the first response from the URL, rather than just let InetGet wait for this response without any control. winhttp seemed the obvious way to go, until this roadblock.

Is there another object I might use in the meantime?

By the way, my pc is on a windows LAN at home, if that makes a difference (might be connected to you finding it crash on a server???)

Best Regards

Larry


I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites

Thanks for looking at this.

My goal here is to create a substitute InetGet that has a timeout for the first response from the URL, rather than just let InetGet wait for this response without any control.  winhttp seemed the obvious way to go, until this roadblock.

Is there another object I might use in the meantime?

By the way, my pc is on a windows LAN at home, if that makes a difference (might be connected to you finding it crash on a server???)

Best Regards

Larry

<{POST_SNAPBACK}>

Larry,

I found the bug. It's not about Windows versions, nor networks. It's about WinHTTP itself.

It seems that some versions of WinHTTP.DLL do not support Events. At least in Windows XP it doesn't work with Winhttp.dll versions 5.1.2600.1106 or lower. On my system I got it working with version 5.1.2600.1557.

I modified the ObjEvent() function to check for situations when Events are not supported, so it won't give a 'hard' crash anymore. However, it won't help you in your situation: I can't invent 'Events' when the object does not support them.

WinHTTP seem to have a long list of bugs in the Microsoft Knowledgebase:

http://support.microsoft.com/default.aspx?...kb;en-us;827042 (mar 2005)

http://support.microsoft.com/default.aspx?...kb;en-us;833828 (mar 2005)

http://support.microsoft.com/default.aspx?...kb;en-us;837822 (dec 2004)

http://support.microsoft.com/default.aspx?...kb;en-us;837823 (dec 2004)

http://support.microsoft.com/default.aspx?...kb;en-us;843559 (dec 2004)

Probably the most important is the "BITS 2.0 and WinHTTP 5.1" update:

http://support.microsoft.com/default.aspx?...kb;en-us;842773 (apr 2005)

You could check if you already have this update.

To return to your original question: You don't have to use Events from the WinHTTP object to create a time-out function. The Object has a SetTimeouts() function by it's own.

Here is a code part that could extend 'InetGet' with a given timeout value:

Func _InetGetWithTimeout($URL,$Timeout)
; $URL    Full url
; $Timeout  in milliseconds

 if ObjEvent("AutoIt.Error") = "" then $oTimeout=ObjEvent("AutoIt.Error","TimeoutFunc")
     
 $OInternet=ObjCreate("winhttp.winhttprequest.5.1")
 
; See: http://msdn.microsoft.com/library/en-us/winhttp/http/iwinhttprequest_settimeouts.asp
 $OInternet.SetTimeouts($Timeout, $Timeout, $Timeout, $Timeout)
 
 $OInternet.Open("GET",$URL)
 $oInternet.Send()      ; Will generate a COM Error if timed out.
     
 $oTimeout=""           ; Stop events
 
 If @error then         ; Did we had a timeout?
    Return ""           ; Nothing to return
 Else
    Return $oInternet.Responsetext; Return result
EndIf

EndFunc

Func TimeoutFunc()
; Called when a WinHTTP timed out
    SetError(1)
EndFunc

And to test this function:

$Text=_InetGetWithTimeout("http://www.autoitscript.com",100)
If @error then 
    Msgbox(0,"timeout","Error: A timeout occured")
Else
    Msgbox(0,"OK","OK: _InetGetWithTimeout got no timeout")
EndIf

$Text=_InetGetWithTimeout("http://www.autoitscript.com",2000)
If @error then 
    Msgbox(0,"timeout","Error: A timeout occured")
Else
    Msgbox(0,"OK","OK: _InetGetWithTimeout got no timeout")
EndIf

Regards,

-Sven

Share this post


Link to post
Share on other sites

Larry,

I found the bug. It's not about Windows versions, nor networks. It's about WinHTTP itself.

It seems that some versions of WinHTTP.DLL do not support Events.  At least in Windows XP it doesn't work with Winhttp.dll versions 5.1.2600.1106 or lower. On my system I got it working with version 5.1.2600.1557.

I modified the ObjEvent() function to check for situations when Events are not supported, so it won't give a 'hard' crash anymore.  However, it won't help you in your situation: I can't invent 'Events' when the object does not support them.

WinHTTP seem to have a long list of bugs in the Microsoft Knowledgebase:

http://support.microsoft.com/default.aspx?...kb;en-us;827042 (mar 2005)

http://support.microsoft.com/default.aspx?...kb;en-us;833828 (mar 2005)

http://support.microsoft.com/default.aspx?...kb;en-us;837822 (dec 2004)

http://support.microsoft.com/default.aspx?...kb;en-us;837823 (dec 2004)

http://support.microsoft.com/default.aspx?...kb;en-us;843559 (dec 2004)

Probably the most important is the "BITS 2.0 and WinHTTP 5.1" update:

http://support.microsoft.com/default.aspx?...kb;en-us;842773 (apr 2005)

You could check if you already have this update.

Thanks for the great response, Sven!

I routinely have WXP updated, but just to make sure I used your link and tryed to install the "newest" revision of winHTTP.dll, but the installer said I have a newer one than the one it was trying to install. I do not know how to find the exact version of the DLL, so it is only by this inference that I say I am up to date (which is inconsistent with your findings, if true). Can you tell me how to find the version of the DLL? I opened it as a text file, but couldn't spot a dtate/version, couldn't see it in the add/remove window with updates shown, what else should I do? I would really like to "put this one to bed".

Also thanks for helping me with the timeout issue.

To return to your original question: You don't have to use Events from the WinHTTP object to create a time-out function. The Object has a SetTimeouts() function by it's own.

Here is a code part that could extend 'InetGet' with a given timeout value:

I actually saw this method here, but the description was pretty limited, it does not even give the default value for ResolveTimeout, and when I tried to use it I got errors. Now I see why..I was looking for an error value being returned, "Returns S_OK if successful, or an error value otherwise.", I did not know it acturally created an error condition if timed out that you had to trap. Also I had concerns that if you changed the timeout, this change would be at a higher level, and change it for other HTTP "users" as well. Also, I had concerns that would only check for events every 10-15 msec (ie use same type of algorithms as in the kernel32 sleep).

I am already using a modified version of your code in mine, thanks a great big bunch!! I convinced myself that the timeout setting in one exectuable do not change them in another that is downloading in a loop.

I have also convinced myself that most of the time InetGet is faster than using winHTTP code. What I am able to do is trap those times that the download "gets waylayed" for some reason and can take seconds instead of tens of milliseconds, restart the download and save myself several seconds on these exceptions. It does not always work, but I have been able to drop the occurances of extraordinariily long download times from a couple of percent of downloads to much less than 1%. If you are doing two downloads a second, that makes a big difference. I am actually using SendSetTimeouts (30, 50, 5000, 75) as timeout values, but I might have to change them when the site gets more busy, or even make them dynamic for optimum performance.

I have not determined if the timeout error event has limitations like sleep, but if it does, it does not seem to be bothering my code timing. I think this is because if something "goes wrong", it goes wrong on the seconds time scale, so I reall should not need to worry if it identifies a problem download after 70 msec or 80 msec, compared to 3000 msec the difference is negligable.

Anyway, it is working very well, thanks a lot for the code example and the error trapping (winHTTP and AutoIT) code as well. I think this code is very much worthy of getting put into the help file. I found it a clearer example of error trapping than those in help right now.

If you could tell me how to get the version number of winHTTP that would be great too.

Best Regards

Larry


I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites

..

If you could tell me how to get the version number of winHTTP that would be great too.

Best Regards

Larry

<{POST_SNAPBACK}>

Larry,

Easy enough. Just browse to your @windowsdir\System32, rightclick the file WINHTTP.DLL and choose properties. In the 'version'-tab (how coincidental) you can see the version:

This version of WINHTTP.DLL has the IWinHttpRequestEvents COM interface (IID={F97F4E15-B787-4212-80D1-D380CBBF982E}) which seems not to be present on Windows 2003sp1 systems and your system.

The InetGet() function uses wininet.dll by the way.

Regards,

-Sven

Share this post


Link to post
Share on other sites

Larry,

Easy enough. Just browse to your @windowsdir\System32, rightclick the file WINHTTP.DLL and choose properties. In the 'version'-tab (how coincidental) you can see the version:

This version of WINHTTP.DLL has the IWinHttpRequestEvents COM interface (IID={F97F4E15-B787-4212-80D1-D380CBBF982E}) which seems not to be present on Windows 2003sp1 systems and your system.

The InetGet() function uses wininet.dll by the way.

Regards,

-Sven

<{POST_SNAPBACK}>

I have SP2, and winhttp.dll verison 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158), created 7/14/04, modified 8/4/04. This number seems to be latter than the one you talked about. I couldn't find {F97F4E15-B787-4212-80D1-D380CBBF982E} in a regedit find attempt.

Regards

Larry


I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites

Sven, I still need your help, or someones help: :) winHTTP timeout algorithm sucks. It does not do

while 1
    if download complete  then exitloop
    if elapsed time greater than timeout setting then
          raise error
    else
          wait a SMALL, PREDETERMINED amount of time ;since timeouts are in msec, this small amount of time should be certainly less than 5 msec.
     endif
wend
Instead of waiting a small, predetermined amount of time before checking if the timeout period is over, it waits for a variable amount of time (I suspect event driven within winHTTP or something like that. Below is the code I used to convince myself of this. The first loop usually gives a timed return of greater than 50 msec even though the first timeout is 5 msec. Note that timeouts of 25/90/25/25 seems to run quite some time with no timeout errors on my pc, very small timout settings.

Also the timeouts are cumalative. The last time out is for each packet that is received, not the total elapsed time. So you can end up with the occasional very long time before the operation is timed out. This is back to the same situation with InetGet itself.

SO I am back to wanting to have asynchronous download with my own timeout analysis, but I can't do that with my current verison of winHTTP, (apparently, even though the version number is larger than you suggested) Maybe I need exactly the right version, or maybe there is some other issue. Is it possible to get the right version? I even tried to "over install" the one at your link on what I have, it stops installation and will not proceed since my version is newer than that version.

Sure could some more advice here!

Regards

Larry

$j = 0
While 1
    $j = TimerInit()
    $Text = _InetGetWithTimeout("http://www.autoitscript.com", 5)
    $j = Int(TimerDiff($j))
    If @error Then
        ToolTip("timeout error   " & $j, 500,500)
    Else
        ToolTip("good download  " & $j & "   " & "   " & $Text, 700, 700)
    EndIf
    Sleep(100)
WEnd
Exit
Func _InetGetWithTimeout($URL, $Timeout)
; $URL    Full url
; $Timeout  in milliseconds
    If ObjEvent ("AutoIt.Error") = "" Then $oTimeout = ObjEvent ("AutoIt.Error", "TimeoutFunc")
    $OInternet = ObjCreate ("winhttp.winhttprequest.5.1")
; See: http://msdn.microsoft.com/library/en-us/winhttp/http/iwinhttprequest_settimeouts.asp
;~ $OInternet.SetTimeouts($Timeout, $Timeout, $Timeout, $Timeout);original timeout line from Sven
;~  $OInternet.SetTimeouts (25, 90, 25, 25) ;these settings creates no timeouts for my PC/internet connection
    $OInternet.SetTimeouts ($Timeout, 5000, 5000,5000)  
    $OInternet.Open ("GET", $URL)
    $oInternet.Send ()     ; Will generate a COM Error if timed out.
    $oTimeout = ""         ; Stop events
    If @error Then      ; Did we had a timeout?
        ToolTip("timed out   after (ms)" & Int(TimerDiff($j)))
        Sleep(5000)
        Return ""          ; Nothing to return
    Else
        Return $oInternet.Responsetext; Return result
    EndIf
EndFunc  ;==>_InetGetWithTimeout
Func TimeoutFunc()
    ToolTip("TimeoutFunc")
; Called when a WinHTTP timed out
    SetError(1)
EndFunc  ;==>TimeoutFunc

I'm, Lovin' IT, X

Share this post


Link to post
Share on other sites

Need some help here please. From previous responses, my code is OK, my winHTTP revision level is the latest as is latter than the one Sven found to duplicate my error, but I get an error at the line

$SinkObject = ObjEvent ($o_HTTP, "HTTPEvent_")

Any suggestions as to what to look at next?

Regards

Larry


I'm, Lovin' IT, X

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