Recent

Author Topic: [Solved] TProcess.ExitStatus not working on Windows?  (Read 3965 times)

Pascal

  • Hero Member
  • *****
  • Posts: 932
[Solved] TProcess.ExitStatus not working on Windows?
« on: October 12, 2018, 01:23:02 pm »
I can't get the exit status of an external script actual. I tried many ways of calling the external script.
- TProcess with cmd /c myscript.cmd parameter
- TProcess with path\myscript parameter
- RunCommandInDir

The script runs and sets errorlevel to 9 but the exitstatus is always 0.

Any ideas?
« Last Edit: October 14, 2018, 06:58:49 am by Pascal »
laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: TProcess.ExitStatus not working on Windows?
« Reply #1 on: October 12, 2018, 02:21:18 pm »
What is the exitcode? (we have exitstatus and exitcode).
Specialize a type, not a var.

Pascal

  • Hero Member
  • *****
  • Posts: 932
Re: TProcess.ExitStatus not working on Windows?
« Reply #2 on: October 12, 2018, 02:39:56 pm »
What is the exitcode? (we have exitstatus and exitcode).

ExitCode returns 0 while process is running and returns ExitStatus when finished:
Code: Pascal  [Select][+][-]
  1. Function TProcessnamemacro.GetExitCode : Integer;
  2.  
  3. begin
  4.   if Not Running then
  5.     Result:=GetExitStatus
  6.   else
  7.     Result:=0
  8. end;
laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TProcess.ExitStatus not working on Windows?
« Reply #3 on: October 12, 2018, 03:36:07 pm »
hello,
you can try runcommandindir from process unit :
Code: Pascal  [Select][+][-]
  1. function RunCommandIndir(
  2.   const curdir: string;
  3.   const exename: string;
  4.   const commands: array of string;
  5.   out outputstring: string;
  6.   out exitstatus: Integer;
  7.   Options: TProcessOptions = []
  8. ):Integer;
  9.  

Quote
RunCommandInDir will execute binary exename with command-line options commands, setting curdir as the current working directory for the command. The Options are taken into consideration (poRunSuspended,poWaitOnExit are removed from the set). The output of the command is captured, and returned in the string OutputString. The function waits for the command to finish, and returns True if the command was started succesfully, False otherwise. In the case where the return value is an integer, it is zero for success, and -1 on error.

If a ExitStatus parameter is specified the exit status of the command is returned in this parameter.

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Pascal

  • Hero Member
  • *****
  • Posts: 932
Re: TProcess.ExitStatus not working on Windows?
« Reply #4 on: October 12, 2018, 05:09:58 pm »
hello,
you can try runcommandindir from process unit :
Code: Pascal  [Select][+][-]
  1. function RunCommandIndir(
  2.   const curdir: string;
  3.   const exename: string;
  4.   const commands: array of string;
  5.   out outputstring: string;
  6.   out exitstatus: Integer;
  7.   Options: TProcessOptions = []
  8. ):Integer;
  9.  

Quote
RunCommandInDir will execute binary exename with command-line options commands, setting curdir as the current working directory for the command. The Options are taken into consideration (poRunSuspended,poWaitOnExit are removed from the set). The output of the command is captured, and returned in the string OutputString. The function waits for the command to finish, and returns True if the command was started succesfully, False otherwise. In the case where the return value is an integer, it is zero for success, and -1 on error.

If a ExitStatus parameter is specified the exit status of the command is returned in this parameter.

Friendly, J.P

Well, i did, see original post. In fact it just encapsulates TProcess. So internally it uses TProcess.ExitStatus.
laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: TProcess.ExitStatus not working on Windows?
« Reply #5 on: October 12, 2018, 06:00:31 pm »
File 1: test1.cmd

Code: [Select]
  exit /b 7

file 2 exectest.pas

Code: [Select]
{$mode delphi}
uses process ;
var ex : integer;
    outp:string;
begin
  writeln(Runcommandindir('.','cmd.exe',['/c','test1.cmd'],outp,ex));  // returns 0 on success execution, -1 otherwise
   writeln(ex);  // prints exitstatus.
end.

prints

Code: [Select]
0
7

If I change the code in test.cmd to "8" and rerun, I get 0 8

So what is exactly the problem?

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TProcess.ExitStatus not working on Windows?
« Reply #6 on: October 12, 2018, 06:09:20 pm »
you can also try TprocessEx from ProcessUtils unit of fpcUpDeluxe project. :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Bt_GoExClick(Sender: TObject);
  2. var
  3.   Proc: TProcessEx;
  4. begin
  5.    try
  6.    Proc := TProcessEx.Create(nil);
  7.    Proc.Executable := 'cmd.exe';
  8.    Proc.Parameters.Add('/C');
  9.    Proc.Parameters.Add('ping.exe juju');
  10. //Proc.Parameters.Add('ping.exe 127.0.0.1');
  11.    Proc.OnErrorM:=@(ProcessError);
  12.    Proc.OnOutputM:=@(ProcessOutput);
  13.    Proc.Execute();
  14.    MemConsole.Append(inttoStr(Proc.ExitStatus));
  15.    MemConsole.Append(inttoStr(Proc.ExitCode));
  16.    finally
  17.      Proc.Free;
  18.      Proc := nil;
  19.    end;
With ping.exe 127.0.0.1 i have exitCode and exitStatus to 0 and with ping.exe juju i have exitCode and exitStatus to 1.
« Last Edit: October 12, 2018, 06:14:07 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: TProcess.ExitStatus not working on Windows?
« Reply #7 on: October 13, 2018, 02:12:01 am »
I don't think using the CMD to execute a ping.exe is going to return an exit code from the ping.exe app

 you started CMD and that is where the exit code is coming from, from my point of view that is.

 Directly call the ping.exe in the process and then try using "GetExitCOdeProess(ProcessHandle, StorageVariable)" before
 freeing the Tprocess…
The only true wisdom is knowing you know nothing

Pascal

  • Hero Member
  • *****
  • Posts: 932
Re: TProcess.ExitStatus not working on Windows?
« Reply #8 on: October 13, 2018, 06:19:19 am »
I found the problem:
There are three nested scripts. The inner script calls "exit /b 9" on error but this does not get handed over to the initially called script.
Also %ERRORLEVEL% is 9, ExitStatus is still 0.
To solve this i added "exit /b %ERRORLEVEL%" to the end of the initially called script.

Then it also makes no difference if i call the script directly or with "cmd /c".

I would have thought that ExitStatus would have been set to the value of %ERRORLEVEL% automatically  :'(

Anyway, many thanks for all the hints here!
laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: TProcess.ExitStatus not working on Windows?
« Reply #9 on: October 13, 2018, 02:09:04 pm »
I would have thought that ExitStatus would have been set to the value of %ERRORLEVEL% automatically  :'(

This is one of the command.com/cmd.exe differences. In cmd.exe errorlevel is just an environment variable which life stops if its shell ends.

 

TinyPortal © 2005-2018