Jump to content

[run] Append StdOut to console?


Go to solution Solved by TheXman,

Recommended Posts

Hello,

What is the right to loop through StdOut and append it to the console? The following replaces it, so I can't see what's going on:

$StartTimer = TimerInit()
Local $sOutput
Local $iReturn = Run($LINE, $OUTPUTDIR, @SW_HIDE,$STDOUT_CHILD + $STDERR_CHILD)
If @error Then Exit MsgBox($MB_ICONERROR, "Error", "Run failed.")
Do
    $sOutput = StdoutRead($iReturn)
    If @error Then ExitLoop
    ;TODO how to check reached EOF or error?
    ;TODO how to append to console instead of replacing?
    ConsoleWrite($sOutput & @CRLF)
Until Not ProcessExists($iReturn)
$StopTimer = TimerDiff($StartTimer)

Thank you.

---

Edit: This doesn't work: The console flickers

Do
    $sOutput = ConsoleRead() & @CRLF
    $sOutput &= StdoutRead($iReturn) & @CRLF
    ConsoleWrite($sOutput)
Until Not ProcessExists($iReturn)

 

Edited by littlebigman
Link to comment
Share on other sites

  • Solution

There are multiple ways to get the STDOUT/STDERR from a process.  If you need the info in real-time, then you can read the STDOUT/STDERR in a loop.  If you can wait until the process has completed, then you can get the STDOUT/STDERR in a single read.  Below, you will find 3 different examples of getting STDOUT (using a loop, using redirection, and using ProcessWaitClose).  Notice the execution times.  Using ProcessWaitClose is much slower than the other 2 methods.

#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d

#include <Constants.au3>
#include <File.au3>


stdout_processwaitclose_read_example()
stdout_redirect_example()
stdout_read_loop_example()

Func stdout_redirect_example()
    Local $hTimer    = TimerInit()

    Local $sCmdLine  = "", _
          $sStdOut   = "", _
          $sTempFile = _TempFile()

    Local $iExitCode = 0, _
          $iTicks    = 0

    ;Build command line and run it
    $sCmdLine  = StringFormat(@ComSpec & ' /c dir c:\ > "%s"', $sTempFile)
    $iExitCode = RunWait($sCmdLine, "", @SW_HIDE)
    If @error Then Return MsgBox($MB_ICONERROR, "Run Error", "Run function failed.")

    ;Get elapsed time
    $iTicks = TimerDiff($hTimer)

    ;Read STDOUT
    $sStdOut = FileRead($sTempFile)
    FileDelete($sTempFile)

    ;Display results
    ConsoleWrite("===========================================" & @CRLF)
    ConsoleWrite("STDOUT Redirection Example"  & @CRLF)
    ConsoleWrite("Cmd:            " & $sCmdLine  & @CRLF)
    ConsoleWrite("Exit Code:      " & $iExitCode & @CRLF)
    ConsoleWrite("Execution time: " & StringFormat("%.3f seconds", $iTicks / 1000) & @CRLF & @CRLF)
    ConsoleWrite("Output" & @CRLF)
    ConsoleWrite($sStdOut & @CRLF)
EndFunc

Func stdout_processwaitclose_read_example()
    Local $hTimer    = TimerInit()

    Local $sCmdLine  = "", _
          $sStdOut   = ""

    Local $iPid      = 0, _
          $iExitCode = 0, _
          $iTicks    = 0

    ;Build command line and run it
    $sCmdLine = @ComSpec & " /c dir c:\"
    $iPid     = Run($sCmdLine, "", @SW_HIDE, $STDERR_MERGED)
    If @error Then Return MsgBox($MB_ICONERROR, "Run Error", "Run function failed.")

    ;Wait for process to end and get exit code
    ProcessWaitClose($iPid)
    $iExitCode = @extended

    ;Get elapsed time
    $iTicks = TimerDiff($hTimer)

    ;Read STDOUT
    $sStdOut = StdoutRead($iPid)

    ;Display results
    ConsoleWrite("===========================================" & @CRLF)
    ConsoleWrite("STDOUT ProcessWaitClose Example"  & @CRLF)
    ConsoleWrite("Cmd:            " & $sCmdLine  & @CRLF)
    ConsoleWrite("Exit Code:      " & $iExitCode & @CRLF)
    ConsoleWrite("Execution time: " & StringFormat("%.3f seconds", $iTicks / 1000) & @CRLF & @CRLF)
    ConsoleWrite("Output" & @CRLF)
    ConsoleWrite($sStdOut & @CRLF)
EndFunc

Func stdout_read_loop_example()
    Local $hTimer    = TimerInit()

    Local $sCmdLine  = "", _
          $sStdOut   = ""

    Local $iPid      = 0, _
          $iTicks    = 0

    ConsoleWrite("===========================================" & @CRLF)

    ;Build command line and run it
    $sCmdLine = @ComSpec & " /c dir c:\"
    $iPid     = Run($sCmdLine, "", @SW_HIDE, $STDERR_MERGED)
    If @error Then Return MsgBox($MB_ICONERROR, "Run Error", "Run function failed.")

    ;Read & display stdout until EOF
    While 1
        $sStdOut = StdoutRead($iPid)
        If @error Then ExitLoop
        ConsoleWrite($sStdOut)
    WEnd

    ;Get elapsed time
    $iTicks = TimerDiff($hTimer)

    ;Display results
    ConsoleWrite(@CRLF)
    ConsoleWrite("STDOUT Read Loop Example"  & @CRLF)
    ConsoleWrite("Cmd:            " & $sCmdLine  & @CRLF)
    ConsoleWrite("Execution time: " & StringFormat("%.3f seconds", $iTicks / 1000) & @CRLF & @CRLF)
EndFunc

Output:

===========================================
STDOUT ProcessWaitClose Example
Cmd:            C:\Windows\system32\cmd.exe /c dir c:\
Exit Code:      0
Execution time: 0.269 seconds

Output
 Volume in drive C is System
 Volume Serial Number is 2415-44AF

 Directory of c:\

01/04/2023  10:36 AM    <DIR>          APCPowerChuteConfig
06/24/2023  12:05 AM    <DIR>          Commands
08/21/2016  11:37 AM    <DIR>          Dell
01/28/2022  11:17 AM    <DIR>          ESD
03/16/2019  04:55 PM    <DIR>          FtpRoot
12/29/2016  07:00 PM    <DIR>          Intel
07/13/2009  10:20 PM    <DIR>          PerfLogs
06/12/2023  10:31 AM    <DIR>          Portable Apps
06/29/2023  07:04 AM    <DIR>          Program Files
06/07/2023  04:03 PM    <DIR>          Program Files (x86)
01/09/2021  01:20 PM    <DIR>          Projects
06/29/2023  09:09 AM    <DIR>          Temp
03/11/2022  10:12 AM    <DIR>          Users
06/26/2023  04:11 PM    <DIR>          Utils
03/19/2023  01:00 AM    <DIR>          Windows
               0 File(s)              0 bytes
              15 Dir(s)  761,011,408,896 bytes free

===========================================
STDOUT Redirection Example
Cmd:            C:\Windows\system32\cmd.exe /c dir c:\ > "C:\Temp\~wqugzpr.tmp"
Exit Code:      0
Execution time: 0.014 seconds

Output
 Volume in drive C is System
 Volume Serial Number is 2415-44AF

 Directory of c:\

01/04/2023  10:36 AM    <DIR>          APCPowerChuteConfig
06/24/2023  12:05 AM    <DIR>          Commands
08/21/2016  11:37 AM    <DIR>          Dell
01/28/2022  11:17 AM    <DIR>          ESD
03/16/2019  04:55 PM    <DIR>          FtpRoot
12/29/2016  07:00 PM    <DIR>          Intel
07/13/2009  10:20 PM    <DIR>          PerfLogs
06/12/2023  10:31 AM    <DIR>          Portable Apps
06/29/2023  07:04 AM    <DIR>          Program Files
06/07/2023  04:03 PM    <DIR>          Program Files (x86)
01/09/2021  01:20 PM    <DIR>          Projects
06/29/2023  09:12 AM    <DIR>          Temp
03/11/2022  10:12 AM    <DIR>          Users
06/26/2023  04:11 PM    <DIR>          Utils
03/19/2023  01:00 AM    <DIR>          Windows
               0 File(s)              0 bytes
              15 Dir(s)  761,011,404,800 bytes free

===========================================
 Volume in drive C is System
 Volume Serial Number is 2415-44AF

 Directory of c:\

01/04/2023  10:36 AM    <DIR>          APCPowerChuteConfig
06/24/2023  12:05 AM    <DIR>          Commands
08/21/2016  11:37 AM    <DIR>          Dell
01/28/2022  11:17 AM    <DIR>          ESD
03/16/2019  04:55 PM    <DIR>          FtpRoot
12/29/2016  07:00 PM    <DIR>          Intel
07/13/2009  10:20 PM    <DIR>          PerfLogs
06/12/2023  10:31 AM    <DIR>          Portable Apps
06/29/2023  07:04 AM    <DIR>          Program Files
06/07/2023  04:03 PM    <DIR>          Program Files (x86)
01/09/2021  01:20 PM    <DIR>          Projects
06/29/2023  09:12 AM    <DIR>          Temp
03/11/2022  10:12 AM    <DIR>          Users
06/26/2023  04:11 PM    <DIR>          Utils
03/19/2023  01:00 AM    <DIR>          Windows
               0 File(s)              0 bytes
              15 Dir(s)  761,011,408,896 bytes free

STDOUT Read Loop Example
Cmd:            C:\Windows\system32\cmd.exe /c dir c:\
Execution time: 0.010 seconds

 

Link to comment
Share on other sites

I'll append to this thread, although it's now a GUI issue.

While converting the code to a GUI, for some reason, the Edit box displays nothing. Does it need to be refreshed or something?

Case $OK
    _GUICtrlButton_Enable($OK, False) ; to prevent user from clicking while CLI app running

    Local $iReturn = Run($LINE, $OUTPUTDIR, @SW_HIDE,$STDOUT_CHILD + $STDERR_CHILD)
    If @error Then Exit MsgBox($MB_ICONERROR, "Error", "Run failed.")
    Local $sOutput = Null
    ;nothing in Edit box
    ;Doesn't catch any error from CLI
    While True
        $sOutput &= StdoutRead($iReturn) & @CRLF
        If @error Then ExitLoop
        GUICtrlSetData($Edit1, $sOutput)
        ;TODO Append + scroll
    WEnd
    $sOutput &= "Done." & @CRLF
    GUICtrlSetData($Edit1, $sOutput)
    ConsoleWrite($sOutput)

---

Edit: Still flickers

Case $OK
    _GUICtrlButton_Enable($OK, False)

    Local $iReturn = Run($LINE, $OUTPUTDIR, @SW_HIDE,$STDOUT_CHILD + $STDERR_CHILD)
    If @error Then Exit MsgBox($MB_ICONERROR, "Error", "Run failed.")
    Local $sOutput = Null
    While True
        $sOutput = StdoutRead($iReturn) & @CRLF
        If @error Then ExitLoop
        ConsoleWrite($sOutput)
        ;_GUICtrlEdit_AppendText($Edit1, @CRLF & $sOutput)
        ;_GUICtrlEdit_AppendText($Edit1, $sOutput)

        _GUICtrlEdit_BeginUpdate($Edit1)
        _GUICtrlEdit_AppendText($Edit1, $sOutput)
        _GUICtrlEdit_EndUpdate($Edit1)

    WEnd
    _GUICtrlEdit_AppendText($Edit1, @CRLF & "Done." & @CRLF)
    ConsoleWrite("Done." & @CRLF)

---

Edit: Better, but still flickers

GUICtrlSetData($Edit1, $sOutput,1) ; 1 = the string is inserted at the current insertion point (caret).
Edited by littlebigman
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...