Jump to content

_RunDos and StdErr


Recommended Posts

Hiya,

I'm trying to use _RunDos in an AutoIt script and the command is definately running, but I can't tell the result nicely.

I'd really like to be able to output the result to the StdErr (or to a file which I can print to the StdErr)

The code I'm having a problem with is just one line that looks like this:

_RunDos($Command)

I'm not sure how to modify it to output the details of what happened as a result of the command to the StdErr

If anyone could help I'd really appreciate it.

 

Thanks

 

Link to comment
Share on other sites

Almost, but not exactly. First, you have a rogue equals-sign (StdoutRead=($pid)) that needs to go. Then, you will want to either wait for the process to close or have the reading done in a loop, since not all the output may come in in the first buffer.

The helpfile contains a working example: https://www.autoitscript.com/autoit3/docs/functions/StdoutRead.htm

Note: if you just want the stdout from a dos command redirected to the stderr stream, dos supports stream redirection: command >&2
Or for the reverse, redirect stderr to stdout: command 2>&1
Or to redirect both the stdout and stderr to a file: command > file 2>&1
(Just in case you didn't know.)

Edited by SadBunny
Markup fail.

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

I also have this function that I wrote that makes it easy for me to call a Windows console application and get its output using a single line of AutoIt code.  I hope it's helpful to you.

#include <Constants.au3>

; #FUNCTION# ====================================================================================================================
; Name ..........: _RunWaitGet

; Description ...: Runs the specified process, waits for it to exit, then returns the contents of its StdOut and/or StdErr streams.
;                  Handy for running command-line tools and getting their output.
; Syntax ........: _RunWaitGet($sProgram, $sWorkingDir, $nShowFlag, $nOptions)
; Parameters ....: $sProgram            - The full path of the program (EXE, BAT, COM, or PIF) to run
;                  $sWorkingDir         - The working directory. Blank ("") uses the current working directory.
;                                         This is not the path to the program.
;                  $nShowFlag           - The "show" flag of the executed program:
;                                            @SW_HIDE = Hidden window (or Default keyword)
;                                            @SW_MINIMIZE = Minimized window
;                                            @SW_MAXIMIZE = Maximized window
;                  $nOptions            - 1 = Capture the StdOut stream only.
;                  $nOptions            - 2 = Capture the StdErr stream only.
;                  $nOptions            - 3 = Capture both the StdOut and StdErr streams.
; Return values .: String value containing the captured contents.
;                  If there was a problem running the process, @error is set to the @error value returned by Run().
;                  Otherwise, @error is 0.
; Author ........: ToasterKing

; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: MsgBox(0,"System Info",_RunWaitGet(@SystemDir & "\systeminfo.exe","",@SW_HIDE,1))
;                  MsgBox(0,"Windows Version",_RunWaitGet(@ComSpec & " /c ver","",@SW_HIDE,1))
; ===============================================================================================================================
Func _RunWaitGet($sProgram,$sWorkingDir,$nShowFlag,$nOptions)
    Local $nRunOptFlags = 0,$sStreamOut = "" ; Initialize variables
    ; Determine flags for parent/child interaction
    If $nOptions = 1 Then
        $nRunOptFlags = $STDOUT_CHILD
    ElseIf $nOptions = 2 Then
        $nRunOptFlags = $STDERR_CHILD
    ElseIf $nOptions = 3 Then
        $nRunOptFlags = $STDOUT_CHILD + $STDERR_CHILD
    EndIf
    Local $hRunStream = Run($sProgram,$sWorkingDir,$nShowFlag,$nRunOptFlags) ; Run the process
    If @error Then Return SetError(@error,@extended,0) ; If there was an error code, return it.  Otherwise...
    While 1 ; Loop until the end of the stream, which indicates that the process has closed it (which usually means the process ended)
        If BitAND($nOptions,1) Then ; If user specified to capture STDOUT stream...
            $sStreamOut &= StdoutRead($hRunStream) ; Append new stream contents to existing variable while removing those contents from the stream.
            If @error = 2 Then ExitLoop ; If stream ended, stop looping.
        EndIf
        If BitAND($nOptions,2) Then ; If user specified to capture STDERR stream...
            $sStreamOut &= StderrRead($hRunStream) ; Append new stream contents to existing variable while removing those contents from the stream.
            If @error = 2 Then ExitLoop ; If stream ended, stop looping.
        EndIf
        Sleep(100) ; To avoid overloading the CPU
    WEnd
    Return SetError(0,0,$sStreamOut) ; Return the captured contents and @error = 0
EndFunc

 

Link to comment
Share on other sites

Thanks toasterking that looks really clever - I have to admit I don't really understand it all that well, If I'm correct could I use it just by modifying the first line after the comments to point at the application I need to run and giving it the path details etc?

Could I use it where the path of the program needs several switches specifying?

eg        C:\Program files\somefilepath\myapplication.exe /SERVER=myserver /USER=myusername /PASSWORD=mypassword /FILE=filetoprocess

I'd pull the command together into a single variable first.

 

Link to comment
Share on other sites

No need to change the function. Just call it, like this:

$output = _RunWaitGet(@ComSpec & " /c dir *.exe /s /a", "c:\temp", @SW_HIDE, 1)
MsgBox(0, 0, $output)

Note 1: the @ComSpec & " /c part (in which the @ComSpec refers to the path to your cmd.exe) is necessary if you're going to run internal dos prompt commands (like dir).
Note 2: the last parameter, that I set to 1, determines whether to capture stdout, stderr or both (see function comments).

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

  • 2 weeks later...

You should put this in the examples section.

​I just added it to the examples section.  I made some minor changes:  I changed the parameter order, made some parameters optional, added an option to return when the stream closes or when the process ends, and made waiting for the process ends the default.

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...