fly Posted March 13, 2006 Share Posted March 13, 2006 I have a process that I'm calling via Run so that I can get StdoutRead info from it. After the process is complete, how could I somehow check the exit code to make sure it actually finished okay? -or- How could I get StdoutRead info from a process using RunWait? Thanks for any help guys! Link to comment Share on other sites More sharing options...
Xenobiologist Posted March 13, 2006 Share Posted March 13, 2006 I have a process that I'm calling via Run so that I can get StdoutRead info from it. After the process is complete, how could I somehow check the exit code to make sure it actually finished okay?-or-How could I get StdoutRead info from a process using RunWait?Thanks for any help guys!Hi, what about starting a batch file and get the errorlevel with echo %errorlevel%?So long,Mega Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
MHz Posted March 14, 2006 Share Posted March 14, 2006 Just posted a solution here in Script'n'Scraps. Link to comment Share on other sites More sharing options...
fly Posted March 14, 2006 Author Share Posted March 14, 2006 Just posted a solution here in Script'n'Scraps.Wow, thanks! Link to comment Share on other sites More sharing options...
fly Posted March 14, 2006 Author Share Posted March 14, 2006 Okay what am I doing wrong here? $runScan = Run(@ComSpec & ' /c "' & $datastore & "\" & GUICtrlRead($userCombo) & '\USMT\scanstate.exe" ' & $datastore & "\" & GUICtrlRead($userCombo) & " /user:" & $domain & "\" & GUICtrlRead($userCombo) & " " & $scanSwitch, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) $handle = _ProcessOpenHandle($runScan) While ProcessExists($runscan) Sleep(10) WEnd $exitCode = _ProcessGetExitCode($runScan, $handle) MsgBox(0, "", $exitCode) I always get an exit code of 0. Is it cause I'm actually launching a program called scanstate? Cause it appears that its only getting the PID of CMD.EXE and not the actual scanstate.exe program. I tried taking out the ComSpec part, so that CMD isn't launched, but it just errors out. Wasn't sure if I should post this question here or in the Scripts thread... Link to comment Share on other sites More sharing options...
fly Posted March 14, 2006 Author Share Posted March 14, 2006 Hmmm, I must be doing something wrong here. I even changed it to this and I still get an exit code of 0. $runScan = Run(@ComSpec & ' /c "' & $datastore & "\" & GUICtrlRead($userCombo) & '\USMT\scanstate.exe" ' & $datastore & "\" & GUICtrlRead($userCombo) & " /user:" & $domain & "\" & GUICtrlRead($userCombo) & " " & $scanSwitch, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) While Not ProcessExists("scanstate.exe") Sleep(10) WEnd $runScan = ProcessExists("scanstate.exe") $handle = _ProcessOpenHandle($runScan) While ProcessExists($runscan) Sleep(10) WEnd $exitCode = _ProcessGetExitCode($runScan, $handle) MsgBox(0, "", $exitCode) Link to comment Share on other sites More sharing options...
MHz Posted March 15, 2006 Share Posted March 15, 2006 Okay what am I doing wrong here? $runScan = Run(@ComSpec & ' /c "' & $datastore & "\" & GUICtrlRead($userCombo) & '\USMT\scanstate.exe" ' & $datastore & "\" & GUICtrlRead($userCombo) & " /user:" & $domain & "\" & GUICtrlRead($userCombo) & " " & $scanSwitch, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) $handle = _ProcessOpenHandle($runScan) While ProcessExists($runscan) Sleep(10) WEnd $exitCode = _ProcessGetExitCode($runScan, $handle) MsgBox(0, "", $exitCode) I always get an exit code of 0. Is it cause I'm actually launching a program called scanstate? Cause it appears that its only getting the PID of CMD.EXE and not the actual scanstate.exe program. I tried taking out the ComSpec part, so that CMD isn't launched, but it just errors out. Wasn't sure if I should post this question here or in the Scripts thread...Your example code above looks correct. And Yes, you are testing CMD for exitcode. If CMD has exited with 0 and the program scanstate.exe has exited with non 0, then you either need to change youe command to read the %errorlevel% of scanstate.exe and use Exit %errorlevel%, ... or You use ProcessExists directly after the Run() command to return the PID of scanstate.exe so you can get the exitcode directly from it. Ensure that the PID that you are getting the exitcode from has indeed exited for successful output of exitcode. Link to comment Share on other sites More sharing options...
fly Posted March 15, 2006 Author Share Posted March 15, 2006 But scanstate isn't exiting with a return code of 0. If my code is right, then something isn't working. Previously, I used: $runscan = RunWait(@ComSpec & ' /c "' & $datastore & "\" & GUICtrlRead($userCombo) & '\USMT\scanstate.exe" ' & $datastore & "\" & GUICtrlRead($userCombo) & " /user:" & $domain & "\" & GUICtrlRead($userCombo) & " " & $scanSwitch) If $runscan = 0 Then usmtLog("Scanstate completed successfully") Else usmtLog("ERROR " & $runscan & " - Scanstate failed to complete" & @CRLF) Return("Scanstate failed to complete.") EndIf and if I closed the DOS box that popped up, it would error out. Using this new code, I don't get an error if I end the process via task manager (since no box pops up). Doing it via task manager shouldn't give it a 0 exit code, should it? Link to comment Share on other sites More sharing options...
MHz Posted March 15, 2006 Share Posted March 15, 2006 I notice that in your command with using comspec, that you are protecting the path to the executable with double quotes, but the switches witch contain some of the same variables have no double quotes around them. If you forcefully close comspec, then the exitcode may end up as unknown, as you did not let the task complete. For an example of how to get the exitcode of comspec with Run() used, then you could test this to show that it can be done. expandcollapse popup$pid = Run(@ComSpec & ' /c Exit 3') $handle = _ProcessOpenHandle($pid) ProcessWaitClose($pid) $exitcode = _ProcessGetExitCode($pid, $handle) MsgBox(0, '', $exitcode) $handle = _ProcessOpenHandle($pid) Func _ProcessOpenHandle($i_Pid) ; Return the process handle of a PID $h_Process = DllCall('kernel32.dll', _ 'ptr', 'OpenProcess', _ 'int', 0x400, _ 'int', 0, _ 'int', $i_Pid) If Not @error Then Return $h_Process Return Not SetError(1) EndFunc Func _ProcessGetExitCode($i_Pid, $h_Process, $i_ProcessCloseHandle = 1) ; Return Process Exitcode of a Process Handle and close Handle as default Local $i_ExitCode, $v_Placeholder, $i_Error = 0 If ProcessExists($i_Pid) Then $i_Error = 3 Else If IsArray($h_Process) Then $i_ExitCode = DllCall('kernel32.dll', _ 'ptr', 'GetExitCodeProcess', _ 'ptr', $h_Process[0], _ 'int_ptr', $v_Placeholder) If @error Then $i_Error = 1 EndIf EndIf ; Close the process handle of a PID If $i_Error = 4 Or $i_ProcessCloseHandle Then DllCall('kernel32.dll', _ 'ptr', 'CloseHandle', _ 'ptr', $h_Process) If @error Then $i_Error = $i_Error + 2 EndIf If $i_Error Then Return Not SetError($i_Error) Return $i_ExitCode[2] EndFunc You may still need to tell comspec to exit with %errorlevel% or to monitor scanstate.exe PID directly by using ProcessExists() to get the PID of scanstate.exe and act on the PID. Link to comment Share on other sites More sharing options...
fly Posted March 15, 2006 Author Share Posted March 15, 2006 I notice that in your command with using comspec, that you are protecting the path to the executable with double quotes, but the switches witch contain some of the same variables have no double quotes around them. I have in some of my comments: ; Doesn't work with quotes around datastore. I have no idea why. The same batch file works fine. If you forcefully close comspec, then the exitcode may end up as unknown, as you did not let the task complete.Using the alternate method I posted with RunWait, closing via task manager did not result in a return code of 0. hmmm For an example of how to get the exitcode of comspec with Run() used, then you could test this to show that it can be done. expandcollapse popup$pid = Run(@ComSpec & ' /c Exit 3') $handle = _ProcessOpenHandle($pid) ProcessWaitClose($pid) $exitcode = _ProcessGetExitCode($pid, $handle) MsgBox(0, '', $exitcode) $handle = _ProcessOpenHandle($pid) Func _ProcessOpenHandle($i_Pid) ; Return the process handle of a PID $h_Process = DllCall('kernel32.dll', _ 'ptr', 'OpenProcess', _ 'int', 0x400, _ 'int', 0, _ 'int', $i_Pid) If Not @error Then Return $h_Process Return Not SetError(1) EndFunc Func _ProcessGetExitCode($i_Pid, $h_Process, $i_ProcessCloseHandle = 1) ; Return Process Exitcode of a Process Handle and close Handle as default Local $i_ExitCode, $v_Placeholder, $i_Error = 0 If ProcessExists($i_Pid) Then $i_Error = 3 Else If IsArray($h_Process) Then $i_ExitCode = DllCall('kernel32.dll', _ 'ptr', 'GetExitCodeProcess', _ 'ptr', $h_Process[0], _ 'int_ptr', $v_Placeholder) If @error Then $i_Error = 1 EndIf EndIf ; Close the process handle of a PID If $i_Error = 4 Or $i_ProcessCloseHandle Then DllCall('kernel32.dll', _ 'ptr', 'CloseHandle', _ 'ptr', $h_Process) If @error Then $i_Error = $i_Error + 2 EndIf If $i_Error Then Return Not SetError($i_Error) Return $i_ExitCode[2] EndFunc You may still need to tell comspec to exit with %errorlevel% or to monitor scanstate.exe PID directly by using ProcessExists() to get the PID of scanstate.exe and act on the PID. Can you explain this a little more? What does the exit 3 do in the comspec? I also tried getting the PID of scanstate.exe directly, but that didn't help either. Thank you SO MUCH for all the help man. Link to comment Share on other sites More sharing options...
MHz Posted March 15, 2006 Share Posted March 15, 2006 Can you explain this a little more? What does the exit 3 do in the comspec? I also tried getting the PID of scanstate.exe directly, but that didn't help either.I have done similar with scanstate below. The Exit 3 was to make comspec return an exitcode of 3 for the AutoIt script test to retrieve. I am getting a return exitcode of 0 for success and 1 for error. Does seem different to code number of errorlevel for some reason. I have added some comments into the code to mention the steps. expandcollapse popup; run scanstate $pid = Run('scanstate.exe /all ' & @HomeDrive & '\SS_OutPut', '', @SW_HIDE, 2) ; get the process handle immediately $handle = _ProcessOpenHandle($pid) ; get the stdout data Global $data While 1 $data &= StdOutRead($pid) If @error Then ExitLoop WEnd ; need to ensure process has exited before checking exitcode ProcessWaitClose($pid) ; check exitcode with the process handle and then close handle $exitcode = _ProcessGetExitCode($pid, $handle) ; show stdout data MsgBox(0, '$data', $data) ; show exitcode MsgBox(0, '$exitcode', $exitcode) Exit Func _ProcessOpenHandle($i_Pid) ; Return the process handle of a PID $h_Process = DllCall('kernel32.dll', _ 'ptr', 'OpenProcess', _ 'int', 0x400, _ 'int', 0, _ 'int', $i_Pid) If Not @error Then Return $h_Process Return Not SetError(1) EndFunc Func _ProcessGetExitCode($i_Pid, $h_Process, $i_ProcessCloseHandle = 1) ; Return Process Exitcode of a Process Handle and close Handle as default Local $i_ExitCode, $v_Placeholder, $i_Error = 0 If ProcessExists($i_Pid) Then $i_Error = 3 Else If IsArray($h_Process) Then $i_ExitCode = DllCall('kernel32.dll', _ 'ptr', 'GetExitCodeProcess', _ 'ptr', $h_Process[0], _ 'int_ptr', $v_Placeholder) If @error Then $i_Error = 1 EndIf EndIf ; Close the process handle of a PID If $i_Error = 4 Or $i_ProcessCloseHandle Then DllCall('kernel32.dll', _ 'ptr', 'CloseHandle', _ 'ptr', $h_Process) If @error Then $i_Error = $i_Error + 2 EndIf If $i_Error Then Return Not SetError($i_Error) Return $i_ExitCode[2] EndFunc Link to comment Share on other sites More sharing options...
fly Posted March 17, 2006 Author Share Posted March 17, 2006 I have done similar with scanstate below. The Exit 3 was to make comspec return an exitcode of 3 for the AutoIt script test to retrieve. I am getting a return exitcode of 0 for success and 1 for error. Does seem different to code number of errorlevel for some reason. I have added some comments into the code to mention the steps. expandcollapse popup; run scanstate $pid = Run('scanstate.exe /all ' & @HomeDrive & '\SS_OutPut', '', @SW_HIDE, 2) ; get the process handle immediately $handle = _ProcessOpenHandle($pid) ; get the stdout data Global $data While 1 $data &= StdOutRead($pid) If @error Then ExitLoop WEnd ; need to ensure process has exited before checking exitcode ProcessWaitClose($pid) ; check exitcode with the process handle and then close handle $exitcode = _ProcessGetExitCode($pid, $handle) ; show stdout data MsgBox(0, '$data', $data) ; show exitcode MsgBox(0, '$exitcode', $exitcode) Exit Func _ProcessOpenHandle($i_Pid) ; Return the process handle of a PID $h_Process = DllCall('kernel32.dll', _ 'ptr', 'OpenProcess', _ 'int', 0x400, _ 'int', 0, _ 'int', $i_Pid) If Not @error Then Return $h_Process Return Not SetError(1) EndFunc Func _ProcessGetExitCode($i_Pid, $h_Process, $i_ProcessCloseHandle = 1) ; Return Process Exitcode of a Process Handle and close Handle as default Local $i_ExitCode, $v_Placeholder, $i_Error = 0 If ProcessExists($i_Pid) Then $i_Error = 3 Else If IsArray($h_Process) Then $i_ExitCode = DllCall('kernel32.dll', _ 'ptr', 'GetExitCodeProcess', _ 'ptr', $h_Process[0], _ 'int_ptr', $v_Placeholder) If @error Then $i_Error = 1 EndIf EndIf ; Close the process handle of a PID If $i_Error = 4 Or $i_ProcessCloseHandle Then DllCall('kernel32.dll', _ 'ptr', 'CloseHandle', _ 'ptr', $h_Process) If @error Then $i_Error = $i_Error + 2 EndIf If $i_Error Then Return Not SetError($i_Error) Return $i_ExitCode[2] EndFunc Thanks for all the help man. it works now! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now