[fpc-pascal] Executing external process that executes another one

leledumbo leledumbo_cool at yahoo.co.id
Mon Apr 13 12:55:50 CEST 2009


(If somebody ever reads the same post in Lazarus forum, please re-read this
one since there are some differences)
I'm making another GUI for Octave (a MATLAB like programming language and
environment) because the currently available ones are either buggy, memory
consuming, or slow (or combination of them).

I'm using TProcess to communicate with Octave with these options:

// enable communication through pipe,
// avoid console box
Options:=[poUsePipes,poNoConsole];

The problems are:
1. Octave's plotting capability is done by another program (GNU Plot) called
by Octave. Using above approach, no GNU plot window ever appears though the
Octave process remains responsive. What should be done to solve it? Well, I
could parse the command and if it deals with plotting I'll start another
process that calls GNU Plot. But I assume that this is too messy and effort
duplicating (because Octave already does this beautifully).

2. When an error occurs, the process dies after giving its error message
(the message is printed). I'm sure of it because both Active and Running
property is false. The app uses the same handler for stdout and stderr. The
code:

procedure TMainForm.OctavePromptInput(ACmdBox: TCmdBox; Input: String);
var
  BytesWritten: LongInt;
begin
  if (Input='quit') or (Input='exit') then Close;
  { Cmdbox trims new line, so we need to add it manually before passing
input to
    Octave process }
  Input:=Input+#10;
  BytesWritten:=OctaveProcess.Input.Write(Input[1],Length(Input));
  // It happens when after the process dies because of error
  if BytesWritten<>Length(Input) then ShowMessage('Why is this happening
(T_T) ?');
  StartPrompt;
end;

procedure TMainForm.ReadOutputIdleTimerTimer(Sender: TObject);

  procedure ProcessStream(Stream: TInputPipeStream);
  var
    Buffer: String;
    BytesRead: Integer;
    BytesAvailable: LongWord;
  begin
    with Stream do begin
      BytesAvailable:=NumBytesAvailable;
      BytesRead:=0;
      while BytesAvailable>0 do begin
        SetLength(Buffer,BytesAvailable);
        BytesRead:=Read(Buffer[1],BytesAvailable);
        OctavePrompt.Write(Copy(Buffer,1,BytesRead));
        BytesAvailable:=NumBytesAvailable;
      end;
    end;
  end;

begin
  // Separate StdOut and StdErr handler, so each can have its own color set
  ProcessStream(OctaveProcess.Output);
  OctavePrompt.TextColors(clRed,clWhite);
  // If NumBytesAvailable>0 the process sends message and dies
  ProcessStream(OctaveProcess.StdErr);
  OctavePrompt.TextColors(clBlue,clWhite);
end;

-- 
View this message in context: http://www.nabble.com/Executing-external-process-that-executes-another-one-tp23020765p23020765.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.




More information about the fpc-pascal mailing list