lgodfrey Posted July 21, 2005 Share Posted July 21, 2005 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_") ExitI can't identifiy anything wrong, help please. Larry I'm, Lovin' IT, X Link to comment Share on other sites More sharing options...
/dev/null Posted July 21, 2005 Share Posted July 21, 2005 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 * Link to comment Share on other sites More sharing options...
bshoenhair Posted July 21, 2005 Share Posted July 21, 2005 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_") ExitI 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" ? Link to comment Share on other sites More sharing options...
lgodfrey Posted July 22, 2005 Author Share Posted July 22, 2005 catch the COM errors to figure out what's the problem. See help file index: Obj/COM Reference. Read section: COM Error Handling.CheersKurt<{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 EndfuncThe 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 Link to comment Share on other sites More sharing options...
SvenP Posted July 22, 2005 Share Posted July 22, 2005 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 Link to comment Share on other sites More sharing options...
lgodfrey Posted July 23, 2005 Author Share Posted July 23, 2005 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 EndfuncAnything you see wrong?RegardsLarry I'm, Lovin' IT, X Link to comment Share on other sites More sharing options...
SvenP Posted July 23, 2005 Share Posted July 23, 2005 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?RegardsLarry<{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 SP4Windows 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 Link to comment Share on other sites More sharing options...
lgodfrey Posted July 23, 2005 Author Share Posted July 23, 2005 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 SP4Windows 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 RegardsLarry I'm, Lovin' IT, X Link to comment Share on other sites More sharing options...
SvenP Posted July 23, 2005 Share Posted July 23, 2005 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 RegardsLarry<{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) EndFuncAnd 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") EndIfRegards,-Sven Link to comment Share on other sites More sharing options...
lgodfrey Posted July 24, 2005 Author Share Posted July 24, 2005 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 RegardsLarry I'm, Lovin' IT, X Link to comment Share on other sites More sharing options...
SvenP Posted July 24, 2005 Share Posted July 24, 2005 ..If you could tell me how to get the version number of winHTTP that would be great too.Best RegardsLarry<{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 Link to comment Share on other sites More sharing options...
lgodfrey Posted July 25, 2005 Author Share Posted July 25, 2005 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.RegardsLarry I'm, Lovin' IT, X Link to comment Share on other sites More sharing options...
lgodfrey Posted July 25, 2005 Author Share Posted July 25, 2005 Sven, I still need your help, or someones help: winHTTP timeout algorithm sucks. It does not dowhile 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 wendInstead 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!RegardsLarryexpandcollapse popup$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 Link to comment Share on other sites More sharing options...
lgodfrey Posted July 27, 2005 Author Share Posted July 27, 2005 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 Link to comment Share on other sites More sharing options...
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