Jump to content

Recommended Posts

Posted (edited)

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
  • Solution
Posted

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

 

Posted (edited)

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

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
  • Recently Browsing   0 members

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