Dagorath Posted July 30, 2007 Share Posted July 30, 2007 In my script, called SCRIPT, I call an external executable, called X, and read it's stdout. I invoke X with... $handle = run ( "X.exe", "", @SW_HIDE, $STDOUT_CHILD ) Then SCRIPT reads every byte in the stream and then X closes, as expected. SCRIPT repeats the above operation every 3 minutes for days, weeks, even months. The problem is that every time run() invokes X, 4 handles get created and only 2 of those handles "die" when X closes. The other 2 live until SCRIPT closes. Those 2 seem to begin life as named pipes and are renamed to Device\null after X closes. They don't die until SCRIPT exits. Obviously, since SCRIPT repeats the above operation every 3 minutes for many weeks, several thousand of these "orphaned" handles are left laying about doing nothing other than bothering the bejeezus out of me. And I have a strong feeling that one day Windows will run out of handles to assign to my dear SCRIPT and then it's all going to go KABLOOEY. I know the 4 handles are opening but only 2 close because I see it in Process Explorer (PE) while SCRIPT runs. For those of you unfamiliar with process Process Explorer, it's a Task Manager replacement from Sys Internals (acquired by Microsoft 1 year ago). The handle count is viewable in PE's upper pane. If you open PE's lower pane and highlight SCRIPT in the upper pane then the details of the handles opening and closing and the names assigned to them are displayed in the lower pane along with many other details. PE shows the handles as type File.Are the 2 orphaned handles unavoidable? Is this a bug in AutoIT? Or is that just the way it is in Windows? Is there any way to force the handles to close other than exiting SCRIPT? I suppose I could start SCRIPT in a second script that allows SCRIPT to run for a few hours then kills SCRIPT and restarts it. BTW, I've tried FileClose($handle) after X closes but that does no good at all. Link to comment Share on other sites More sharing options...
PsaltyDS Posted July 30, 2007 Share Posted July 30, 2007 You didn't show any code, so it isn't possible to sure this is your issue, but likely you didn't read everything out of the $STDOUT_CHILD pipe. Discussed here: handle/memory leak with Run/StdoutRead?, NOBUG Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Dagorath Posted July 31, 2007 Author Share Posted July 31, 2007 You didn't show any code, so it isn't possible to sure this is your issue, but likely you didn't read everything out of the $STDOUT_CHILD pipe. Discussed here: handle/memory leak with Run/StdoutRead?, NOBUG Thanks for directing me to that thread I ran the last code snippet posted there and found that it leaks handles. I am not sure if the poster is saying that code snippet should work or not. Seems to me it should but it definitely leaks handles here. Anyway, see my script below. It runs hello.bat (see further down) which puts out 10 lines. My script reads hello.bat's stdout, adds a ! to the line and stores the line in $array. When it encounters EOF it stores a solitary ! char. Uncomment the _ArrayDisplay() line to see the contents of the array after it's full. expandcollapse popup#include <Constants.au3> #include <Array.au3> Opt("MustDeclareVars", 1) HotKeySet("{ESC}","Quit") dim $array[13] while 1 fill_array($array) ;_ArrayDisplay($array) sleep(5000) wend ; ============================================================================= Func fill_array(byref $array) dim $count = 1 dim $eos = false const $stream = Run("hello.bat", "" , "", $STDOUT_CHILD) sleep(1000) do $array[$count] = get_line($stream, $eos) $count = $count + 1 until $eos EndFunc ; ============================================================================= Func get_line(const $stream, byref $eos) dim $line = "", $char = "" do $char = StdoutRead($stream,1) ; Sets @error to non-zero if EOF is reached $eos = @error if $eos then msgbox(0, "", "End of stream", 5) if $char <> @cr and $char <> @lf then $line = $line & $char until $char = @CR or $eos return $line & "!" EndFunc ; ============================================================================= func quit() Exit EndFunc ; ============================================================================= Below is the hello.bat @echo off echo Hello world echo Hello world echo Hello world echo Hello world echo Hello world echo Hello world echo Hello world echo Hello world echo Hello world echo Hello world 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