Sign in to follow this  
Followers 0
therks

Exit code + StdoutRead/StderrRead

4 posts in this topic

Is there any way to retrieve the exit code from a process while also being able to use StdoutRead/StderrRead?

Share this post


Link to post
Share on other sites



Have a look at this example that pulled from this and edited.

Example.au3

#include <Constants.au3>
#include "ProcessExitCode.au3"
 
$iPid = Run(@ComSpec & ' /c dir /g', @WindowsDir, @SW_SHOW, $STDERR_CHILD + $STDOUT_CHILD)
$hHandle = _ProcessGetHandle($iPid)
ShowStdOutErr($hHandle)
$iExitCode = _ProcessGetExitCode($iPid)
_ProcessCloseHandle($hHandle)
MsgBox(0, "Program returned with exit code:", $iExitCode)
 
$iPid = Run(@ComSpec & ' /c dir', @WindowsDir, @SW_SHOW, $STDERR_CHILD + $STDOUT_CHILD)
$hHandle = _ProcessGetHandle($iPid)
ShowStdOutErr($hHandle)
$iExitCode = _ProcessGetExitCode($hHandle)
_ProcessCloseHandle($hHandle)
MsgBox(0, "Program returned with exit code:", $iExitCode)
 
Func ShowStdOutErr($l_Handle, $ShowConsole = 1)
    Local $Line, $tot_out, $err1 = 0, $err2 = 0
    Do
        Sleep(10)
        $Line = StdoutRead($l_Handle)
        $err1 = @error
        $tot_out &= $Line
        If $ShowConsole Then ConsoleWrite($Line)
        $Line = StderrRead($l_Handle)
        $err2 = @error
        $tot_out &= $Line
        If $ShowConsole Then ConsoleWrite($Line)
    Until $err1 And $err2
    Return $tot_out
EndFunc   ;==>ShowStdOutErr

ProcessExitCode.au3

#include-once
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessGetHandle()
; Description ...: Returns a handle from use of Run().
; Syntax.........: _ProcessGetHandle($iPID)
; Parameters ....: $iPID - ProcessID returned from a Run() execution
; Return values .: On Success - Returns Process handle while Run() is executing (use above directly after Run() line with only PID parameter)
;                 On Failure - 0
; Author ........: MHz (Thanks to DaveF for posting these DllCalls in Support Forum)
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ProcessGetHandle($iPID) ;Return handle of given PID
    Local Const $PROCESS_QUERY_INFORMATION = 0x0400
    Local $avRET = DllCall("kernel32.dll", "ptr", "OpenProcess", "int", $PROCESS_QUERY_INFORMATION, "int", 0, "int", $iPID)
    If @error Then
        Return SetError(1, 0, 0)
    Else
        Return $avRET[0]
    EndIf
EndFunc   ;==>_ProcessGetHandle
 
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessCloseHandle()
; Description ...: Closes a handle from use of Run().
; Syntax.........: _ProcessCloseHandle($hProc)
; Parameters ....: $hProc - Process handle
; Return values .: On Success - Closes Process handle after a Run() has executed.;
;                 On Failure - 0
; Author ........: MHz (Thanks to DaveF for posting these DllCalls in Support Forum), PsaltyDS
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ProcessCloseHandle($hProc) ;Close process handle
    Local $avRET = DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
    If @error Then
        Return SetError(1, 0, 0)
    Else
        Return 1
    EndIf
EndFunc   ;==>_ProcessCloseHandle
 
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessGetExitCode()
; Description ...: Returns a handle/exitcode from use of Run().
; Syntax.........: _ProcessGetExitCode($hProc)
; Parameters ....: $hProc   - Process handle
; Return values .: On Success - Returns Process Exitcode when Process does not exist.
;                 On Failure - 0
; Author ........: MHz (Thanks to DaveF for posting these DllCalls in Support Forum), PsaltyDS
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ProcessGetExitCode($hProc) ;Get process exit code from handle
    Local $t_ExitCode = DllStructCreate("int")
    Local $avRET = DllCall("kernel32.dll", "int", "GetExitCodeProcess", "ptr", $hProc, "ptr", DllStructGetPtr($t_ExitCode))
    If @error Then
        Return SetError(1, 0, 0)
    Else
        Return DllStructGetData($t_ExitCode, 1)
    EndIf
EndFunc   ;==>_ProcessGetExitCode

Adam

Share this post


Link to post
Share on other sites

Thanks, that works perfectly. And I can use _WinAPI_OpenProcess() and _WinAPI_CloseHandle() from the WinAPI.au3 include. Sorry for the horrendous reply time, I don't get back here often.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

This a simpler quick and dirty way

FileDelete("C:\temp\errorlevel.txt")

$file = fileopen(@TempDir & "\CMD.bat",2)
FileWrite($file,"start /wait c:\temp\test2.exe" & @CRLF)
FileWrite($file,"echo %errorlevel% > C:\temp\errorlevel.txt" & @CRLF)
FileClose($file)

$PID = run(@TempDir & "\CMD.bat")


While ProcessExists($PID)
wend

$file = fileopen("C:\temp\errorlevel.txt",0)
msgbox(0,"",fileread($file))
fileclose($file)
Edited by castens

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

  • Similar Content

    • MightyMalcolm
      SoundPlay sometimes(!) not working in a programme called by Run()
      By MightyMalcolm
      Hello everyone,
       
      I am not 100% sure how to phrase my problem so I'm sorry if the issue has been addressed elsewhere. Here is my situation: I have added a file called MyStartup.exe (generated by AutoIt) to the list of programmes to launch on startup via the Windows registry on my laptop. As soon as it is running, this file will display a 3 minutes (tooltip) countdown and in the end call Run("Another.exe"). The latter is an AutoIt script, too. Among other things, it contains a few SoundPlay() commands, but for some reason, there is no sound coming at all! Strangely, however, when i manually run the MyStartup.exe and let it do its job, THEN the Another.exe plays sounds properly.
      I can only guess what might be the matter here, since the same procedure (autostart) works fine on my other PC.
       
      Any help would be greatly appreciated
    • BetaLeaf
      [Solved] How do I launch an app as it's own parent process?
      By BetaLeaf
      I have 3 processes that I am trying to work with:
      The ControlCenter (Cannot Edit) and handles the other 2 processes. The ControlCenter will launch and close processes as requested by the user.
      The Launcher (Can Edit) and launches an installer.
      The Script (Can Edit) and automates the above installer.
       
      My issue is, ControlCenter will terminate the Launcher and all of it's child processes. I need the script to continue running after the Launcher has been closed by the ControlCenter. How do I get the Launcher to launch the script in it's own parent process so it does not get terminated when the ControlCenter terminates the launcher and all child processes?
       
      Sorry if this is confusing. I am terrible at explaining things. Autism can be a pain to deal with sometimes.
    • bobbyab9987
      How to open multiple files in only one instance of the corresponding program?
      By bobbyab9987
      Hi friends,
      Suppose MyProgram is a tabbed program, meaning that it allows for opening multiple files in the same instance.
      I want to open File1, File2 and File3 in one instance of MyProgram from an AutoIT script. How can I do this?
      I have read the AutoIT Help File about "ShellExecute" and "Run", but I have found nothing helpful.
      Thanks for reading my question. Any answer would be very appreciated.
       
       
    • Skysnake
      [SOLVED] Regex in 7 Zip Std Out (and error)
      By Skysnake
      Perhaps someone would benefit off this.  I made heavy use of the Help file example.
      Only question I have here, is is there a better way to do the Regex for finding "error|ERROR|Error" in the source string?  Thx
      Example7zPwd() Func Example7zPwd() ;-- Local $iPID = Run(@ComSpec & " /c DIR Example.au3", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Local $iPID = Run(@ComSpec & " /c 7za t -pmasale myzip.zip ", "c:\files\testing", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Local $sOutput = "" Local $myError = 0 ConsoleWrite("$myError:" & $myError & @CRLF) While 1 $sOutput = StdoutRead($iPID) If @error Then ; Exit the loop if the process closes or StdoutRead returns an error. ExitLoop EndIf MsgBox($MB_SYSTEMMODAL, "Stdout Read:", $sOutput, 5) If StringRegExp($sOutput, '\b(error|ERROR|[Ee]rror)\b', 0) Then $myError = $myError + 1 ;ConsoleWrite("$sOutput: " & $sOutput & @CRLF) ConsoleWrite("$myError: " & $myError & @CRLF) WEnd While 1 $sOutput = StderrRead($iPID) If @error Then ; Exit the loop if the process closes or StderrRead returns an error. ExitLoop EndIf MsgBox($MB_SYSTEMMODAL, "Stderr Read:", $sOutput, 15) WEnd ConsoleWrite("$myError: " & $myError & @CRLF) If $myError > 0 Then MsgBox(64, "An Error Occurred", "The upgrade may be incomplete. An error occurred") EndIf If StringRegExp($sOutput, '\b(error|ERROR|[Ee]rror)\b', 0) Then Is the Regex here optimized?
       
       
    • NiceBoy1234
      Open Windows Shell Explorer
      By NiceBoy1234
      How can I start the Window SHell Explorer after closing it with this:
      Run('TASKKILL /F /PID ' & ProcessExists('explorer.exe'))