Sign in to follow this  
Followers 0
Valhalla1

StdoutRead/StderrRead problem, output getting chopped off short

3 posts in this topic

#1 ·  Posted (edited)

Hello,

lets say I have a java app "Solve" and I pass it 3 paramters on the command line, and it outputs like this :

C:\TEST\solve> java Solve a b c

Output line 1 : foo

Output line 2 : bar

Output line 3 : foobar

I'm trying to automate this in autoit and capture all 3 lines of output to a string variable. However, it is only capturing lines 1 and 2, and ignoring line 3. I guess because there is an empty whitespace line after line 2 and before line 3. How can I get it to capture everything ?

Here's the code thats only capturing line 1 and 2 :

$a = "A"
$b = "B"
$c = "C"

$line2 = Solve()

Msgbox(0,"",$line2)



Func Solve()

    Local $result = Run(@ComSpec & " /c java.exe Solve "& " " & $a & " " & $b & " " & $c, "C:\TEST\solve", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    Local $line
    While 1
        $line = StdoutRead($result)
        If @error Then ExitLoop
        ;MsgBox(0, "STDOUT read:", $line)
    Wend

    While 1
        $line = StderrRead($result)
        If @error Then ExitLoop
        ;MsgBox(0, "results", $line)
        Return($line)
    Wend
    Return($line)

EndFunc
Edited by Valhalla1

Share this post


Link to post
Share on other sites



But maybe your missing LINE 3 is a problem of the /C command.

I tried it here with a fake_java.bat (to emulate your java)

@echo off
echo Output line 1 : foo
echo Output line 2 : bar
echo.
echo Output line 3 : foobar

As you see the BAT is very short (I know java takes longer to start up...). Sometimes when I start this it gives me the full expected output but (often) on the first run, it takes a little bit longer and the BAT is finished before the output was read and there for the last lines is missing. So maybe your scritp is already good in that way. So how to solve this?

option 1) Use "/K" and not "/C" and kill the ProcessID in the end (but you may than get the prompt in the end)

option 2) use a .CMD to start your java with a PAUSE in the end and use StdinWrite($command,"X") to send anykey(X) to the pause command

option 3) ???

I played a little with the code....

#include <Constants.au3>
#include <GUIConstants.au3>
global $a = "A"
global $b = "B"
global $c = "C"

$line2 = Solve()
Msgbox(0,"Result of function Solve()",$line2)
$line2 = Solve2()
Msgbox(0,"Result in function Solve2 modified solve()",$line2)
$line2 = Solve3()
Msgbox(0,"Result in function Solve3 (own)",$line2)

Exit


Func Solve3()

    Local $command = Run(@ComSpec & " /k fake_java.bat Solve "& " " & $a & " " & $b & " " & $c, @Scriptdir, @SW_HIDE,$STDERR_CHILD + $STDOUT_CHILD)
    Local $read
    Do
        If StdoutRead($command,1,True) Then
            $read = StdoutRead($command)
            If @error Then ExitLoop
            consolewrite("In Function:"&$read&@CRLF)
        EndIf
    Until $read <> ""

    Return($read)

EndFunc

Func Solve2()

    Local $result = Run(@ComSpec & " /c fake_java.bat Solve "& " " & $a & " " & $b & " " & $c, @Scriptdir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    Local $line
    Do
        If StdoutRead($result,1,True) Then
            $line = StdoutRead($result)
            If @error Then ExitLoop
            consolewrite("STDOUT results:"& $line&@CRLF)
        EndIf
        If StderrRead($result,1,True) Then
            $line = StderrRead($result)
            If @error Then ExitLoop
            consolewrite("STDERR results:"& $line&@CRLF)
        EndIf

    Until $line <> ""

    Return($line)

EndFunc

Func Solve()

    Local $result =  Run(@ComSpec & " /c fake_java.bat Solve "& " " & $a & " " & $b & " " & $c, @Scriptdir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    Local $line
    While 1
        $line = StdoutRead($result)
        If @error Then ExitLoop
        consolewrite("STDOUT results:"& $line&@CRLF)
    Wend

    While 1
        $line = StderrRead($result)
        If @error Then ExitLoop
        consolewrite("STDERR results:"& $line&@CRLF)
        Return($line)
    Wend
    Return($line)

EndFunc

In your code I think you constantly polll the Stdout/err with

$line = StderrRead($result)

If you also use consolewrite you will see the difference to

If StdoutRead($result,1,True) Then
            $line = StdoutRead($result)

I'm not sure about the return value anyway, because if STDOUT and STDERR happens you only return STDOUT. In case only STDERR happens you retunr STDERR (or did I get it wrong?)

Maybe use two vars instead of line and return an array?

Share this post


Link to post
Share on other sites

Have you try like this ?

Func Solve()
    Local $result = Run(@ComSpec & " /c java.exe Solve " & $a & " " & $b & " " & $c, "C:\TEST\solve", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    Local $line, $allline
    While $result
        $line = StdoutRead($result)
        If Not @error And $line <> '' Then $allline = $allline & $line
        $line = StderrRead($result)
        If Not @error And $line <> '' Then $allline = $allline & $line      
    Wend
    Return($allline)
EndFunc

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

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