TProcess hängt sich auf

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
ws7
Beiträge: 18
Registriert: Mi 20. Jul 2011, 22:27

TProcess hängt sich auf

Beitrag von ws7 »

Hallo,

mit meiner Procedure ProcessCmdline (Siehe unten) lese ich den Output diverser Commandline Programme ein.
Das funktioniert schonn einige Zeit wunderbar, auch bei größeren Ausgabedaten im Bereich 200k Byte.

Nun hängt das ganze aber, ohne dass sich sie Größe des Output wesentlich geändert hätte.
Der Prozess mit dem Commandline-Programm beendet siche nie und ProcessCmdline() bekommt keine Daten mehr und wartet in der repeat Schleife natürlich endlos.

Wenn ich den Commandline-Prozess abschieße, hat ProcessCmdline() nur ca. 80 Zeilen des Output gelesen. Insgesamt sollten es aber ca. 1800 Zeilen sein.

Woran kann das liegen, kann das ein Fehler in TProcess sein?
Warum hängt der Commandline Prozess schon bei 80 Zeilen, wenn im anderen Falls problemlos 1800 Zeilen funktionieren?
Kann es von den Ausgabedaten selber abhängen (z. B. Sonderzeichen)?
Wie kann ich das ganze irgendwie debuggen?


Viele Grüße
WS

Code: Alles auswählen

procedure ProcessCmdline(cmdLine:string; strList:TStringList);
const
  READ_BYTES = 4096;
var
  AProcess  : TProcess;
  ms        : TMemoryStream;
  bytesRead : integer;
  n         : integer;
begin
  bytesRead := 0;
  ms := TMemoryStream.Create;
  ms.SetSize(READ_BYTES); 
 
  AProcess := TProcess.Create(nil);
  AProcess.Options := AProcess.Options + [poUsePipes];
  AProcess.ShowWindow := swoHIDE;
  AProcess.CommandLine := cmdLine;
  AProcess.Execute;
  repeat
    if AProcess.Output.NumBytesAvailable > 0 then begin
      n := 0;
      n := AProcess.Output.Read((ms.Memory+BytesRead)^, READ_BYTES); 
      if n>0 then begin
        inc(BytesRead, n);
        ms.SetSize(BytesRead + READ_BYTES);
      end;
    end;
  until not AProcess.Running;
  ms.SetSize(BytesRead);
 
  strList.Clear;
  strList.LoadFromStream(ms);
  AProcess.Free;
end;

ws7
Beiträge: 18
Registriert: Mi 20. Jul 2011, 22:27

Re: TProcess hängt sich auf

Beitrag von ws7 »

Habe den Fehler nun selber gefunden.

In StdErr wurde von meiner Commandline-Anwendung neuerdings auch noch was geschrieben und das habe ich nicht abgeholt. Darum hat sich das gnaze dann blockert.

ws7
Beiträge: 18
Registriert: Mi 20. Jul 2011, 22:27

Re: TProcess hängt sich auf

Beitrag von ws7 »

ws7 hat geschrieben:Habe den Fehler nun selber gefunden.
In StdErr wurde von meiner Commandline-Anwendung neuerdings auch noch was geschrieben und das habe ich nicht abgeholt. Darum hat sich das gnaze dann blockert.
Und hier noch ein Beispiel wie StdOut und StdErr gleichzeitig gelesen werden und in den beiden TStringList zurückgegeben werden....

Code: Alles auswählen

procedure ProcessCmdline(cmdLine:string; strListStd,strListErr:TStringList);
const
  READ_BYTES = 1024;
var
  ms_std, ms_err   : TMemoryStream;
  Process1         : TProcess;
  pos_std, pos_err : integer;
  n_std, n_err     : integer;
  n_read           : integer;
begin
  pos_std := 0;
  pos_err := 0;
  ms_std := TMemoryStream.Create;
  ms_err := TMemoryStream.Create;
  Process1 := TProcess.Create(nil);
  Process1.Options := Process1.Options + [poUsePipes];
  Process1.ShowWindow := swoHIDE;
  Process1.CommandLine := cmdLine;
  Process1.Execute;
  repeat
    n_std := Process1.Output.NumBytesAvailable;
    n_err := Process1.StdErr.NumBytesAvailable;
    if n_std > 0 then begin
      ms_std.SetSize(pos_std + n_std);
      n_read := Process1.Output.Read((ms_std.Memory+pos_std)^, n_std);
      inc(pos_std, n_read);
    end;
    if n_err > 0 then begin
      ms_err.SetSize(pos_err + n_err);
      n_read := Process1.StdErr.Read((ms_err.Memory+pos_err)^, n_err);
      inc(pos_err, n_read);
    end;
  until not Process1.Running and (n_std=0) and (n_err=0);
  ms_std.SetSize(pos_std);
  ms_err.SetSize(pos_err);
 
  strListStd.Clear;
  strListErr.Clear;
  strListStd.LoadFromStream(ms_std);
  strListErr.LoadFromStream(ms_err);
  Process1.Free;
end;

Antworten