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

    • AnonymousX
      By AnonymousX
      Hello,
      What command would I use to open the following folder directories for:
      Computer/This PC (windows 7/Windows 10)
      Libraries\documents
      Libraries\Pictures
      I know:
       Run("Explorer.exe " & $filepath) ShellExecute($filepath) can be used to open folder locations when you type in the full directory such as "C:\Users\%username%\Documents" but I'm trying to figure out how to use these windows short paths. 
      Thanks,
    • StMaSi
      By StMaSi
      I'm attempting to code a Run or RunWait command that is a little on the long side and contains multiple sets of embedded quotes (as it would be issued from a CMD prompt), but can't for the life of me figure out the containing quotes as pertains to AutoIt. Here's the one-line command as it would be issued via a CMD prompt...
      "\\AppServ\G$\Connectivity\Clients\Citrix\Receiver\14.5.0.10018\CitrixReceiver.exe" ADDLOCAL="ReceiverInside,ICA_Client,WebHelper,SSON,AM,SELFSERVICE,USB,DesktopViewer,Flash,Vd3d" ALLOWADDSTORE=A ALLOWSAVEPWD=A ENABLEPRELAUNCH=Y ENABLE_SSON=Yes STORE0="AppStore;https://receiver.domain.net/Citrix/Apps/discovery;on;AppStore" /EnableCEIP=false /includeSSON /noreboot /silent I've tried so many different combinations of surrounding quotes with Run and RunWait, I just don't understand why it's this difficult to get past this.
      Can anyone assist with this?
      Thank you.
    • WoodGrain
      By WoodGrain
      Hi guys,
      This is probably an obvious one, but I really don't use this command at all so am hoping you can spot my mistake.
      I'm running a powershell script on a schedule with the following script in a function, the function is being called in a loop, but the console process is not closing in the background and I end up with a bunch of console windows running in the background:
      Run(@comspec & ' /k PowerShell.exe -STA -NonInteractive -ExecutionPolicy ByPass -Command "& ''Z:\Powershell\365\GetNextDetails.ps1'' "', "", @SW_HIDE) Thanks!
    • careca
      By careca
      #include <Constants.au3> ListLetter() Func ListLetter() ;$DSK = Run("cmd", '', '', $STDIN_CHILD + $STDOUT_CHILD) $DSK = Run(@ComSpec & " /c diskpart.exe start", '', '', $STDIN_CHILD + $STDOUT_CHILD) ConsoleWrite('$DSK - '& $DSK&' - Error - '& @error &' - '&@MSEC&@CRLF) Sleep(2000) $Read = StdoutRead($DSK, True, False) ConsoleWrite(' - '& @error &' - '&@MSEC&@CRLF) ConsoleWrite('StdoutRead ' &$Read&' - '&@MSEC&@CRLF) EndFunc ;==>ListLetter So, this works with normal console "cmd" why does it error with diskpart? how can i make it read from diskpart?
    • nss
      By nss
      Hi all. I am creating an app that runs a program with the admin privileges using the shellexecute's run as verb, but what my problem is, that no matter what I use to launch the program, it doesn't quite work like the run dialog would (certain programs don't get found, etc.). I've tried using the explorer.exe and passing the program to it, that is unreliable and opens documents folder sometimes instead, I've tried using the @comspec /c and that works better, but still some of the programs aren't being found that would be with the run dialog e.g., if I do @comspec /c diskpart it won't find it, I've even tried setting the working dir, but still no luck. I also tried passing commandline params to C:\WINDOWS\system32\rundll32.exe shell32.dll,#61, but no luck. can anyone help me what way to go in order to be able to launch programs in the run dialog style? is there a function in winapi that run dialog uses that I could use as well? Or what would be the best way to go about this? Any help much appreciated.