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

    • 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')) 
    • TheNorwegianUser
      Shellexecute / Run error
      By TheNorwegianUser
      Okay, so I have a TCP connection set up over some computers, no problem. I recieve the messages without problem, and when I get a specific message over the server, it runs some program. No problem at first. But then, after the whole script has ran for a while, it won't open any program, not even a web page like ShellExecute("www.google.com"). It just returns @error=1. It's nothing wrong with the path, FileExists makes sure of that (Always returns 1). When I then try using Run instead of ShellExecute, I still get an error. Any idea why it just works at first, but then starts to fail every time?
      Relevant for opening a specific file:
      ShellExecute(@DesktopDir & "\Fireplace.mp4") If @error Then FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - ShellExecute Error: " & @error & " & Extended: " & @extended & @CRLF) $Exists=FileExists(@DesktopDir & "\Fireplace.mp4") FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - Exists: " & $Exists & " & exists error: " & @error & " & Extended: " & @extended & @CRLF);;;;;;;;;;; Run(@DesktopDir & "\Fireplace.mp4") If @error Then FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - Run Bål Error: " & @error & " & Extended: " & @extended & @CRLF) EndIfWhole client:
      #Include <_AudioEndpointVolume.au3> #include <Process.au3> TCPStartup() OnAutoItExitRegister("Terminate") $IPAdress="My personal IP..." $Port= Some IP... Local $Socket Connect() While 1 Sleep(50) Recv() If _IsInternetConnected()=False Then Connect(2) WEnd Func Recv() $Recv=TCPRecv($Socket, 2048) If @error>0 Then Connect(@error & " " & @extended) If $Recv="" Then Return FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - Recieved " & $Recv & @CRLF);;;;;;;;;;; $Recv=StringReplace($Recv, @CR, "") CheckForAction($Recv) EndFunc Func Connect($Conn=0) TCPCloseSocket($Socket) FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - Connection mode " & $Conn & @CRLF);;;;;;;;;;; TraySetIcon(@ScriptDir & "\icons\offline.ico") Do Sleep(1000) $Socket=TCPConnect($IPAdress, $Port) Until Not @error TraySetIcon(@ScriptDir & "\icons\online.ico") TCPSend($Socket, "ImMain") EndFunc Func CheckForAction($_Recv) If $_Recv="vg" Then ShellExecute("www.vg.no") Return True EndIf If $_Recv="bål" Or $_Recv="bÃ¥l" Then ShellExecute(@DesktopDir & "\Fireplace.mp4") If @error Then FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - ShellExecute Error: " & @error & " & Extended: " & @extended & @CRLF) $Exists=FileExists(@DesktopDir & "\Fireplace.mp4") FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - Exists: " & $Exists & " & exists error: " & @error & " & Extended: " & @extended & @CRLF);;;;;;;;;;; Run(@DesktopDir & "\Fireplace.mp4") If @error Then FileWrite(@DesktopDir & "\MultiClientMainLog.txt", @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & " - Run Bål Error: " & @error & " & Extended: " & @extended & @CRLF) EndIf Sleep(1000) Send("f") Return True EndIf If $_Recv="exit" Then Send("{ALTDOWN}{F4}{ALTUP}") Return True EndIf If $_Recv="opp" Then Send("{PGUP}") Return True EndIf If $_Recv="ned" Then Send("{PGDN}") Return True EndIf If $_Recv="endc" Then FileWrite(@TempDir & "\endc.txt", "ok") Return True EndIf If $_Recv="startc" Then FileWrite(@TempDir & "\startc.txt", "ok") Return True EndIf If $_Recv="cbål" Or $_Recv="cbÃ¥l" Then FileWrite(@TempDir & "\endc.txt", "ok") Sleep(3000) ShellExecute(@DesktopDir & "\Fireplace.mp4") Sleep(1000) Send("f") Return True EndIf If StringLeft($_Recv, 3)="cmd" Then _RunDOS(StringTrimLeft($_Recv, 4)) Return True EndIf If StringLeft($_Recv, 3)="au3" Then If FileExists(@TempDir & "\Run.au3") Then FileDelete(@TempDir & "\Run.au3") FileWrite(@TempDir & "\Run.au3", StringTrimLeft($_Recv, 4)) ShellExecute(@TempDir & "\Run.au3") Return True EndIf If Stringleft($_Recv, 10)="set volume" Then _SetMasterVolumeLevelScalar(StringTrimLeft($_Recv, 11)) Return True EndIf If StringLeft($_Recv, 4)="send" Then Send(StringTrimLeft($_Recv, 5)) Return True EndIf If StringLeft($_Recv, 4)="www." Then ShellExecute($_Recv) Return True EndIf Return False EndFunc Func _IsInternetConnected() Local $aReturn = DllCall('connect.dll', 'long', 'IsInternetConnected') If @error Then Return SetError(1, 0, False) Return $aReturn[0] = 0 EndFunc ;==>_IsInternetConnected Func Terminate() TCPShutdown() Exit EndFunc 
    • WoodGrain
      Run() executes on some computers but not others
      By WoodGrain
      Hi All,
      I've got a script setup to drop a program into a temp folder and then run it from there, but I have mixed results, the Run() command will work on some computers but not others. The file will be placed into the temp folder in all cases. Running AutoIT 3.3.14.0. The computers are all either Win 7 or 8.1, x64 (exe is compiled to x64 too), UAC is off, all have local admin rights - if I've missed something ask and I'll update the details.
      If Not FileExists (@TempDir & "\HCTB") Then DirCreate(@TempDir & "\HCTB") FileInstall("G:\IT\Downloads\TB\12.0.45471\Host\TB_Setup-sif7r8pgcq.exe", @TempDir & "\HCTB\TB_Setup-sif7r8pgcq.exe", 1) Local $iPID = Run(@TempDir & "\HCTB\TB_Setup-sif7r8pgcq.exe", "") Any suggestions?
      Thanks!