Recent

Author Topic: How to run an external program with RunCommandLoop, while interacting with it?  (Read 717 times)

vsajip

  • New Member
  • *
  • Posts: 26
I want to run an external program and interact with it, but I can't seem to do that with the built-in TProcess.RunCommandLoop functionality. That's because of this loop in TProcess.RunCommandLoop:

Code: Pascal  [Select][+][-]
  1.     while Running do
  2.       begin
  3.         // Only call ReadFromStream if Data from corresponding stream
  4.         // is already available, otherwise, on  linux, the read call
  5.         // is blocking, and thus it is not possible to be sure to handle
  6.         // big data amounts bboth on output and stderr pipes. PM.
  7.         gotoutput:=ReadInputStream(output,BytesRead,OutputLength,OutputString,1);
  8.         // The check for assigned(P.stderr) is mainly here so that
  9.         // if we use poStderrToOutput in p.Options, we do not access invalid memory.
  10.         gotoutputstderr:=false;
  11.         if assigned(stderr) then
  12.             gotoutputstderr:=ReadInputStream(StdErr,StdErrBytesRead,StdErrLength,StdErrString,1);
  13.  
  14.         if (porunidle in options) and not gotoutput and not gotoutputstderr and Assigned(FOnRunCommandEvent) Then
  15.           FOnRunCommandEvent(self,Nil,RunCommandIdle,'');
  16.       end;

Now, I do have poRunIdle in my options, and have assigned OnRunCommandEvent to a handler, but specifically due to the checks for gotoutput and gotoutputstderr, my handler isn't being called. I know I can subclass TProcess and override RunCommandLoop, but is there another way which is simpler?

Also, I see that TRunCommandEventCode has options RunCommandReadOutputString and RunCommandReadOutputStream, but how are these supposed to be used? I see no usages of them in the Lazarus source code.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8819
  • Programming + Glam Metal + Tae Kwon Do = Me
RunCommandLoop is not meant for interactivity. You really need to replicate this while Running loop with your own body.

vsajip

  • New Member
  • *
  • Posts: 26
RunCommandLoop is not meant for interactivity. You really need to replicate this while Running loop with your own body.

Shame. I've done that, thanks. I just wondered if there was a simpler way, but it appears not.

Thaddy

  • Hero Member
  • *****
  • Posts: 17451
  • Ceterum censeo Trumpum esse delendum (Tnx Charlie)
Haver a look at TAsyncProcess. That comes very close to what you want.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

vsajip

  • New Member
  • *
  • Posts: 26
Thanks for the tip.

 

TinyPortal © 2005-2018