Hi,
how would you handle large output and large stderr?
When you read from one and it writes to the other, the read blocks. Then
it keeps writing to the other buffer, till that is full, and then its
write is blocked, and it is deadlocked.
Probably check NumBytesAvailable before reading?
Bye,
Benito
On 02/28/2017 05:28 PM, Michael Van Canneyt wrote:
On Tue, 28 Feb 2017, Graeme Geldenhuys wrote:
Hi,
Can anybody see if there is something wrong with the code shown below.
The code is copied from one of my earlier projects where I call the FPC
compiler and it worked just fine in that project.
In the work I'm doing now, I'm calling the Delphi Command Line Compiler,
and made a few minor tweaks to the code, but this method never seems to
return when Delphi command line compiler is called, and I don't see any
output. If I call other utilities (eg: Git etc) then I do see output and
it works as expected. It's just the Delphi Command Line Compiler that
now seems to be giving troubles.
I would really appreciate it is anybody could spare a moment. Many
thanks.
I marked two areas with "// ???" where I am unsure if I'm doing the
right thing.
poWaitOnExit should not be needed, as this will cause Execute to wait
for process exit...
It seems likely that this will interfere with reading from output:
when the
output buffer is full, the executed process will block.
The rest seems fine.
Also:
It may be that Delphi somehow writes directly to the console buffer,
in that
case you will not catch any output. But then you should see the output on
the screen (just not caught by your process)
Michael.
==================================
function TBuildDelphiProject.RunTProcess(const Binary: string; args:
TStrings): boolean;
const
BufSize = 1024;
var
p: TProcess;
Buf: string;
Count: integer;
i: integer;
LineStart: integer;
OutputLine: string;
begin
p := TProcess.Create(nil);
try
p.Executable := Binary;
// ??? Is poWaitOnExit needed here, it is called later down the code
p.Options := [poUsePipes, poStdErrToOutPut, poWaitOnExit];
// p.CurrentDirectory := ExtractFilePath(p.Executable);
p.ShowWindow := swoShowNormal; // ??? Is this needed?
p.Parameters.Assign(args);
DoLog(etInfo,'Running command "%s" with arguments
"%s"',[p.Executable, p.Parameters.Text]);
p.Execute;
{ Now process the output }
OutputLine:='';
SetLength(Buf,BufSize);
repeat
if (p.Output<>nil) then
begin
Count:=p.Output.Read(Buf[1],Length(Buf));
end
else
Count:=0;
LineStart:=1;
i:=1;
while i<=Count do
begin
if Buf[i] in [#10,#13] then
begin
OutputLine:=OutputLine+Copy(Buf,LineStart,i-LineStart);
writeln(OutputLine);
OutputLine:='';
if (i<Count) and (Buf[i+1] in [#10,#13]) and
(Buf[i]<>Buf[i+1]) then
inc(i);
LineStart:=i+1;
end;
inc(i);
end;
OutputLine:=Copy(Buf,LineStart,Count-LineStart+1);
until Count=0;
if OutputLine <> '' then
writeln(OutputLine);
p.WaitOnExit;
Result := p.ExitStatus = 0;
if Not Result then
Writeln('Command ', p.Executable ,' failed with exit code: ',
p.ExitStatus);
finally
FreeAndNil(p);
end;
end;
==================================
Regards,
Graeme
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/
My public PGP key: http://tinyurl.com/graeme-pgp
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal