Recent

Author Topic: TProcess input  (Read 579 times)

HomeBoy38

  • Jr. Member
  • **
  • Posts: 52
TProcess input
« on: December 23, 2022, 10:51:38 am »
Hi,

I am trying to interface a command line program (so no console shown) but I am stuck on the input part.

Here is the simplified version of my code:
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.BCONClick(Sender: TObject);
  2. var
  3.  AStringList: TStringList;
  4.  MyOutput: String;
  5.  CMD: TProcess;
  6. begin
  7.  CMD := TProcess.Create(nil);
  8.  CMD.Options := [poUsePipes, poStderrToOutPut, poWaitOnExit];
  9.  CMD.Executable := 'myexe';
  10.  CMD.Parameters.Clear;
  11.  CMD.Parameters.Add('param1');
  12.  CMD.Parameters.Add('param2');
  13.  MyOutput := 'yes' + #10;
  14.  CMD.Execute;
  15.  CMD.Input.Write(MyOutput, Length(MyOutput));
  16.  AStringList := TStringList.Create;
  17.  MyOutput := '';
  18.  sleep(100);
  19.  Application.ProcessMessages;
  20.  AStringList.LoadFromStream(CMD.Output);
  21.  MyOutput := AStringList.Strings[AStringList.Count - 1];
  22.  if Copy(MyOutput, 1, 3) = 'err' then
  23.   ShowMessage('error');
  24.  CMD.Free;
  25.  AStringList.Free;
  26. end;
  27.  

While running, 'myexe' can ask for one or more 'yes' to continue, so far, I am trying to input at least the first one.
If an error occurs, I am correctly exiting the 'myexe' and the error message is shown (if everything goes fine, nothing to do).
I really do not understand how to catch the 'Type yes' message from 'myexe', but even more, I do not understand why blindly writing to the input does not work?

Thanks in advance

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 10715
  • FPC developer.
Re: TProcess input
« Reply #1 on: December 23, 2022, 12:22:34 pm »
Have a look at  https://stackoverflow.com/questions/72335247/input-and-output-pipe-in-lazarus-tprocess

and the ZIP that I posted there.  Note that it is best to first test with some simple FPC programs before testing your final target, just in case that program somehow behaves atypically.

Note that your code says to wait on exit (Powaitonexit), and only then sends input.

Edson

  • Hero Member
  • *****
  • Posts: 1276
Re: TProcess input
« Reply #2 on: December 23, 2022, 04:49:37 pm »
To interact with a process I recommend to use my library: https://github.com/t-edson/UnTerminal

It's completely driven by events and have prompt detection so you can answer any question the program ask.
Lazarus 2.0.10 - FPC 3.2.0 - x86_64-win64 on Windows 8

HomeBoy38

  • Jr. Member
  • **
  • Posts: 52
Re: TProcess input
« Reply #3 on: December 26, 2022, 09:26:08 am »
Hi,
First thanks to both of you for your answers.
If I understand correctly, I cannot use TProcess natively to do what I need without wrapping TProcess.

I will make a try on your advices.
During my researches, I have found your codes, once appeared a bit complex for my simple search, and the other one was talking about Minecraft server so I wrongly thought I was leaving my path.

Thanks.

Hartmut

  • Hero Member
  • *****
  • Posts: 634
Re: TProcess input
« Reply #4 on: December 26, 2022, 12:19:11 pm »
For 'TProcess' with redirected input and output I use this code. Works on Windows and Linux.

Code: Pascal  [Select][+][-]
  1. procedure exec_TProcess_InOut(cmd: ansistring; SLK,SLI: TStringList;
  2.                               var SLO: TStringList; var ec,es: longint);
  3.    {calls an external program 'cmd' via 'TProcess' and redirects Input from
  4.     StringList 'SLI' and redirects Output into StringList 'SLO'. Waits until
  5.     the external program has finished.
  6.      - 'SLK' = commandline parameters.
  7.      - 'ec' and 'es' are error codes.
  8.      - 'SLO': must be initialized external}
  9.    var PZ: TProcess;
  10.        s: ansistring;
  11.        n,i: longint;
  12.    begin
  13.    ec:=-1; es:=-1; {unspecific error codes, e.g. if 'cmd' not found}
  14.    PZ:=TProcess.Create(nil);
  15.  
  16.    try
  17.      try
  18.        PZ.Executable:=cmd;
  19.        PZ.Parameters:=SLK;
  20.        PZ.Options:=[poUsePipes];
  21.        PZ.Execute;
  22.  
  23.        n:=SLI.Count;
  24.        for i:=0 to n-1 do
  25.           begin
  26.           s:=SLI.Strings[i] + LineEnding;
  27.           PZ.Input.Write(s[1],length(s));
  28.           end;
  29.  
  30.        while PZ.Running do {wait until external program has finished}
  31.           sleep(50);
  32.  
  33.        SLO.LoadFromStream(PZ.Output);
  34.  
  35.      finally
  36.        ec:=PZ.ExitCode;
  37.        es:=PZ.ExitStatus;
  38.        PZ.Free;
  39.      end; {try2}
  40.  
  41.    except
  42.      on E:Exception do
  43.         begin
  44.         if ec=0 then ec:=-1;
  45.         if es=0 then es:=-1;
  46.         end;
  47.    end; {try1}
  48.    end;
  49.  
  50. procedure Test_TProcess_InOut;
  51.    {Demo for exec_TProcess_InOut()}
  52.    var SLK,SLI,SLO: TStringList;
  53.        cmd: ansistring;
  54.        ec,es: longint;
  55.    begin
  56.    cmd:='my.exe';
  57.    SLK:=TStringList.Create; {commandline parameters: }
  58.       SLK.Add('param1');
  59.       SLK.Add('param2');
  60.    SLI:=TStringList.Create; {create Input-StringList}
  61.       SLI.Add('username');
  62.       SLI.Add('password');
  63.       SLI.Add('y');
  64.    SLO:=TStringList.Create; {create Output-StringList}
  65.  
  66.    exec_TProcess_InOut(cmd,SLK,SLI,SLO, ec,es);
  67.    SLK.Free;
  68.    SLI.Free;
  69.    SLO.Free;
  70.  
  71.    if (ec<>0) or (es<>0) then writeln('ERROR: ec=', ec, ' es=', es);
  72.    end;

HTP

HomeBoy38

  • Jr. Member
  • **
  • Posts: 52
Re: TProcess input
« Reply #5 on: December 26, 2022, 07:27:05 pm »
@marcov: I was not able to input to myexe using your sample code, I did not figure out why and I quit
@Edson: this is too complex for my need by I am sure it will help someone else
@Hartmut: your code is very similar to my tests before I post my question, but yours works  ;D

Thanks for your contribution, on my side, it appears to be closed, but if anyone else needs, you can use my topic

Have a great end of year

 

TinyPortal © 2005-2018