Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-11

Reading from an external process

4 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Richard Mace

Hi All,
I have got the following code from the wiki for creating and reading from an external process. Effectively, I want to capture all of the output from the process "handle.exe", into a StringList so that I can read it to make sure that everything went OK, however, when I run the following code, I am getting a "RunError(103) on the line: WriteLn('-- Going to run: ' + OurCommand);

Any ideas what I'm doing wrong please?

Lazarus 1.0.12 with FPC 2.6.2 Windows XP

procedure TfrmMain.Button1Click(Sender: TObject);
const
  READ_BYTES = 2048;
var
  OurCommand: String;
  OutputLines: TStringList;
  MemStream: TMemoryStream;
  OurProcess: TProcess;
  NumBytes: LongInt;
  BytesRead: LongInt;
begin
  MemStream := TMemoryStream.Create;
  BytesRead := 0;
  OurProcess := TProcess.Create(nil);
  OurCommand:='C:\Documents and Settings\RichardMace\My
Documents\Downloads\SysinternalsSuite\handle.exe';
  WriteLn('-- Going to run: ' + OurCommand);
  OurProcess.CommandLine := OurCommand;
  OurProcess.Options := [poUsePipes];
  WriteLn('-- External program run started');
  OurProcess.Execute;
  while OurProcess.Running do
  begin
    // make sure we have room
    MemStream.SetSize(BytesRead + READ_BYTES);
    // try reading it
    NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^,
READ_BYTES);
    if NumBytes > 0 then
      begin
        Inc(BytesRead, NumBytes);
        Write('.'); //Output progress to screen.
      end
    else begin
      // no data, wait 100 ms
      Sleep(100);
    end;
  end;
  // read last part
  repeat
    // make sure we have room
    MemStream.SetSize(BytesRead + READ_BYTES);
    // try reading it
    NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^,
READ_BYTES);
    if NumBytes > 0 then
      begin
        Inc(BytesRead, NumBytes);
        Write('.');
      end;
  until NumBytes <= 0;
  if BytesRead > 0 then WriteLn;
  MemStream.SetSize(BytesRead);
  memMain.Lines.Add('-- External program run complete');
  OutputLines := TStringList.Create;
  OutputLines.LoadFromStream(MemStream);
  memMain.Lines.Add('-- External program output line count = ' +
IntToStr(OutputLines.Count) + ' --');
  for NumBytes := 0 to OutputLines.Count - 1 do
    begin
      WriteLn(OutputLines[NumBytes]);
    end;
  WriteLn('-- Program end');
  OutputLines.Free;
  OurProcess.Free;
  MemStream.Free;
end;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131105/a0ac81b7/attachment.html>

Reply by email

waldo kitty
to Richard Mace
Richard Mace wrote 6 lines
Hi All, I have got the following code from the wiki for creating and reading from an external process. Effectively, I want to capture all of the output from the process "handle.exe", into a StringList so that I can read it to make sure that everything went OK, however, when I run the following code, I am getting a "RunError(103) on the line: WriteLn('-- Going to run: ' + OurCommand);

i'd guess that the error is only showing up at that point... you have spaces in your command line... what happens if you wrap it in double quotes?

OurCommand:='"C:\Documents and Settings\RichardMace\My
Documents\Downloads\SysinternalsSuite\handle.exe"';

this is a common thing on winwhatever systems...

NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

Sven Barth
to Richard Mace: I have got the following code from the wiki for creating and reading from an external…
Richard Mace wrote 9 lines
Hi All, I have got the following code from the wiki for creating and reading from an external process. Effectively, I want to capture all of the output from the process "handle.exe", into a StringList so that I can read it to make sure that everything went OK, however, when I run the following code, I am getting a "RunError(103) on the line: WriteLn('-- Going to run: ' + OurCommand); Any ideas what I'm doing wrong please?

Is your application (that one which calls handle.exe) compiled as a GUI application or not? (check in the project settings) If it is compiled as a GUI application then disable the option and recompile. An additional console window should now appear when you run the application from within Lazarus in which you'll see your output.
Reason: on Windows the I/O is closed on startup if the application is compiled as a GUI program (Delphi compatible)
Alternatively you could use a Memo. Either you directly use YourMemo.Add('...') or if you want to keep using Writeln, I have a unit sent somewhere on the mailing list some days ago that allows you to assign a memo or edit to a TextFile so that you could use either Writeln(YourFile, '...') or you could override "Output" so that you could keep using Writeln('...').

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131105/a8aedf7c/attachment.html>

Reply by email

Richard Mace
to Sven Barth

Thanks Sven
I've now switched to a memo and thats worked

"Sven Barth" wrote 36 lines
Am 05.11.2013 14:48, schrieb Richard Mace: Hi All, I have got the following code from the wiki for creating and reading from an external process. Effectively, I want to capture all of the output from the process "handle.exe", into a StringList so that I can read it to make sure that everything went OK, however, when I run the following code, I am getting a "RunError(103) on the line: WriteLn('-- Going to run: ' + OurCommand); Any ideas what I'm doing wrong please? Is your application (that one which calls handle.exe) compiled as a GUI application or not? (check in the project settings) If it is compiled as a GUI application then disable the option and recompile. An additional console window should now appear when you run the application from within Lazarus in which you'll see your output. Reason: on Windows the I/O is closed on startup if the application is compiled as a GUI program (Delphi compatible) Alternatively you could use a Memo. Either you directly use YourMemo.Add('...') or if you want to keep using Writeln, I have a unit sent somewhere on the mailing list some days ago that allows you to assign a memo or edit to a TextFile so that you could use either Writeln(YourFile, '...') or you could override "Output" so that you could keep using Writeln('...'). Regards, Sven -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131105/a365cfc5/attachment.html>

Reply by email