Jump to content

Reading stderr w/ RunWait


Recommended Posts

Run returns a PID which can be used with StderrRead. RunWait does not return a PID. I am forcing a call to cmd line function, 7za, to fail but all I can get is the Fatal Error code of 2, not the error string. Is there a way to have my cake, I mean my RunWait and Stderr string too?

Saw this example at StderrRead but if there is no error will it ever exit the loop. Not fond of this kind of loop as it seems it could possibly run forever.

$foo = Run(@ComSpec & " /c dir foo.bar", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

While 1

$line = StdoutRead($foo)

If @error Then ExitLoop

MsgBox(0, "STDOUT read:", $line)

Wend

Thanks,

jh

Edited by hmsSurprise
Link to comment
Share on other sites

Run returns a PID which can be used with StderrRead. RunWait does not return a PID. I am forcing a call to cmd line function, 7za, to fail but all I can get is the Fatal Error code of 2, not the error string. Is there a way to have my cake, I mean my RunWait and Stderr string too?

Saw this example at StderrRead but if there is no error will it ever exit the loop. Not fond of this kind of loop as it seems it could possibly run forever.

$foo = Run(@ComSpec & " /c dir foo.bar", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

While 1

$line = StdoutRead($foo)

If @error Then ExitLoop

MsgBox(0, "STDOUT read:", $line)

Wend

Thanks,

jh

Your example only shows you reading Stdout, but not StdErr as well. If you want your cake and eat it too, then I will assume that you want Stdout, StdErr that Run returns as well as the exitcode that RunWait returns. To have your cake... then look here.

:shocked:

Link to comment
Share on other sites

Thanks for posting. Looks like some very good tools. I apologize for tthe misleading post. I should have shown all the code, the rest was a repeat that fetched stderr instead of stdout.

Running 'd:\Installer\7za x abc' (abc is an invalid name) from a cmd window I get the following message:

Error:

cannot find archive

Using _ProcessOpenHandle and _ProcessGetExitCode I get the exit code 2 which corresponds with what RunWait returns but I am not able to retrieve the error string. Here's what I tried.

$cmd = 'd:\Installer\7za x ' & 'bogusName'

$pid = Run($cmd)

$handle = _ProcessOpenHandle($pid)

While ProcessExists($pid)

Sleep(10)

WEnd

$stderr = StderrRead($pid)

$stdout = StdoutRead($pid)

$extended = @extended

$exitcode = _ProcessGetExitCode($pid, $handle)

MsgBox(0, "$pid: ", $pid)

MsgBox(0,'Exitcode: ', $exitcode)

MsgBox(0,'@error: ', @error)

msgBox(0,'$stdout', $stdout)

msgBox(0,'$stderr', $stderr)

msgBox(0,"extended",@extended) ;Should have conctenated but just kept adding one more at a time.

Thanks again,

jh

Link to comment
Share on other sites

Looks like your reading StdOut and StdErr streams too late as $pid will not exist when you check it because you run a loop untill $pid exists no more.

Try this way instead.

Global $stdout, $stderr
$cmd = 'd:\Installer\7za x ' & '"bogusName"'
$pid = Run($cmd, '', @SW_HIDE, 6)
$handle = _ProcessOpenHandle ($pid)
Do
    $stdout = StdoutRead($pid)
Until @error
Do
    $stderr &= StdErrRead($pid)
Until @error
ProcessWaitClose($pid)

$extended = @extended
$exitcode = _ProcessGetExitCode ($pid, $handle)

MsgBox(0, "$pid: ", $pid)
MsgBox(0, 'Exitcode: ', $exitcode)
MsgBox(0, '@error: ', @error)
MsgBox(0, '$stdout', $stdout)
MsgBox(0, '$stderr', $stderr)
MsgBox(0, "extended", @extended) ;Should have conctenated but just kept adding one more at a time.

I did not fix up your Msgboxes showing @error or @extended as they are too late also to check. @error and @etended only holds the data until the next function call resets them.

Edit:

Added double quotes around your bogusname in vase of space in it.

Also declare vars before using of them.

Edited by MHz
Link to comment
Share on other sites

Thanks for all the effort but I still can't get my string.

Not quite sure I understand the Do Loops. Will they terminate if there is no error? Perhaps I misunderstood the documentation on @error and SetError, but I thought @error would remain zero if no error occurred.

Thanks again,

jh

Link to comment
Share on other sites

Correct. @error remains 0 if no error is returned from the function, but you still need to back it up into a variable if you want to view the status latter, like in a Msgbox.

Your while loop checks the condition at the start of the loop but Do checks the condition at the end of the loop. Do loop is better in the code above as you check for @error after a function call so suits your purpose. StdOutRead amd StdErrRead will both set @error when the streams are closed.

To get your string, sometime you may need to use StdInWrite() to write a @CRLF immediately after the Run() to respond to the child process before it will continue with the stream. VBS in comparison teaches to do this concept by default so sometime us AutoIt users have to StdInWrite as well. Will need to add the flag to Run() before also using StdInWrite().

Edited by MHz
Link to comment
Share on other sites

I've previously posted a UDF called _RunReadStd(), which runs a command, and then returns the exit code, stdout and stderr. You might be able to modify it to suit your needs:

http://www.autoitscript.com/forum/index.php?showtopic=41894

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...