Sign in Join

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

Mailing lists / fpc-pascal / 2015-03

TProcess does not work in Windows XP

16 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

Antonio Sanguigni

Hello,

I know XP is an old OS but some customers of mine still have it !

I'm writing a little software which is calling a console program and I have the need to capture its output. My core TPRocess code is the same as fpc wiki for TProcess and it works very well in Windows 7. My problem is Windows XP I mean, the same code seems does not produce any results.

Any tip ?

Thank you
Antonio

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Antonio Sanguigni
to leledumbo

2015-03-25 5:01 GMT+01:00 leledumbo :

1. Define "does not produce any results."

Simply I cannot get output from console app which I'm trying to run and capture. Again, this is happening just for windows xp. Same procedure (follow code) in Windows 7 is right.

2. Show your code

Yes, you are absolutely right. Here it is. I did not use RunCommand because it does not seem to work for me. Problem was such as above, I mean no output from console app to run.

---------------------- code ---------------
procedure TBurpClient.Run;
begin
  fOurProcess.Options := [poUsePipes] + [poNoConsole];
  fOurProcess.Execute;
  while True do
  begin
    // make sure we have room
    fMemStream.SetSize(fBytesRead + READ_BYTES);
    // try reading it
    fNumBytes := fOurProcess.Output.Read((fMemStream.Memory +
fBytesRead)^, READ_BYTES);
    if fNumBytes > 0 then // All read() calls will block, except the final one.
    begin
      Inc(fBytesRead, fNumBytes);
     // Write('.') //Output progress to screen.
    end
    else
      BREAK // Program has finished execution.
  end;
  fMemStream.SetSize(fBytesRead);
  fOutputLines := TStringList.Create;
  fOutputLines.LoadFromStream(fMemStream);
  fOutputLines.SaveToFile('output.txt');
  CommandOutput := fOutputLines.Text;
  faStringList.Assign(fOutputLines);
  fObjectList.Add(fOutputLines);
  Inc(fIndexOfOL);
//  fOutputLines.Free;
end;
-------------------------------------------------

Thank you.

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Michael Van Canneyt
to Antonio Sanguigni
Antonio Sanguigni wrote 28 lines
2015-03-25 5:01 GMT+01:00 leledumbo : > 1. Define "does not produce any results." Simply I cannot get output from console app which I'm trying to run and capture. Again, this is happening just for windows xp. Same procedure (follow code) in Windows 7 is right. > 2. Show your code Yes, you are absolutely right. Here it is. I did not use RunCommand because it does not seem to work for me. Problem was such as above, I mean no output from console app to run. ---------------------- code --------------- procedure TBurpClient.Run; begin fOurProcess.Options := [poUsePipes] + [poNoConsole]; fOurProcess.Execute; while True do begin // make sure we have room fMemStream.SetSize(fBytesRead + READ_BYTES); // try reading it fNumBytes := fOurProcess.Output.Read((fMemStream.Memory + fBytesRead)^, READ_BYTES); if fNumBytes > 0 then // All read() calls will block, except the final one.
I am not sure this is always correct. Various versions of windows work differently in this regard;
zero (0) may be a valid return value. I suggest you check fOurProcess.IsRunning to break the loop.

Michael.

Reply by email

Antonio Sanguigni
to Michael Van Canneyt

2015-03-25 8:41 GMT+01:00 Michael Van Canneyt :

Show quoted text 21 lines
> ---------------------- code --------------- > procedure TBurpClient.Run; > begin > fOurProcess.Options := [poUsePipes] + [poNoConsole]; > fOurProcess.Execute; > while True do > begin > // make sure we have room > fMemStream.SetSize(fBytesRead + READ_BYTES); > > // try reading it > fNumBytes := fOurProcess.Output.Read((fMemStream.Memory + > fBytesRead)^, READ_BYTES); > if fNumBytes > 0 then // All read() calls will block, except the final > one. I am not sure this is always correct. Various versions of windows work differently in this regard; zero (0) may be a valid return value. I suggest you check fOurProcess.IsRunning to break the loop.

Thank you, I will try it. But debugging I can see the problem is not in the loop. In Windows XP fNumBytes is always zero:

fNumBytes := fOurProcess.Output.Read((fMemStream.Memory +
fBytesRead)^, READ_BYTES);

so it seems the Read of fOurProcess.Output is not giving the expected results.

In Windows 7 it's ok.

Antonio

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Michael Van Canneyt
to Antonio Sanguigni
Antonio Sanguigni wrote 30 lines
2015-03-25 8:41 GMT+01:00 Michael Van Canneyt : >> ---------------------- code --------------- >> procedure TBurpClient.Run; >> begin >> fOurProcess.Options := [poUsePipes] + [poNoConsole]; >> fOurProcess.Execute; >> while True do >> begin >> // make sure we have room >> fMemStream.SetSize(fBytesRead + READ_BYTES); >> >> // try reading it >> fNumBytes := fOurProcess.Output.Read((fMemStream.Memory + >> fBytesRead)^, READ_BYTES); >> if fNumBytes > 0 then // All read() calls will block, except the final >> one. > > > I am not sure this is always correct. Various versions of windows work > differently in this regard; > zero (0) may be a valid return value. I suggest you check > fOurProcess.IsRunning to break the loop. Thank you, I will try it. But debugging I can see the problem is not in the loop. In Windows XP fNumBytes is always zero: fNumBytes := fOurProcess.Output.Read((fMemStream.Memory + fBytesRead)^, READ_BYTES); so it seems the Read of fOurProcess.Output is not giving the expected results.

Read translates directly to a kernel call.

In Windows 7 it's ok.

Once more:
Zero is a valid return value for read from a pipe.

So it can perfectly be that read attempts 50 times returns 0, and only at read attempt 51 you get a positive result.

That is why you must check isRunning, and not rely on the return value of readbytes.

Michael.

Reply by email

Pierre Free Pascal
to Michael Van Canneyt
Show quoted text 60 lines
-----Message d'origine----- De : [mailto:fpc-pascal- De la part de Michael Van Canneyt Envoyé : mercredi 25 mars 2015 09:54 À : FPC-Pascal users discussions Objet : Re: [fpc-pascal] TProcess does not work in Windows XP On Wed, 25 Mar 2015, Antonio Sanguigni wrote: > 2015-03-25 8:41 GMT+01:00 Michael Van Canneyt : >>> ---------------------- code --------------- >>> procedure TBurpClient.Run; >>> begin >>> fOurProcess.Options := [poUsePipes] + [poNoConsole]; >>> fOurProcess.Execute; >>> while True do >>> begin >>> // make sure we have room >>> fMemStream.SetSize(fBytesRead + READ_BYTES); >>> >>> // try reading it >>> fNumBytes := fOurProcess.Output.Read((fMemStream.Memory + >>> fBytesRead)^, READ_BYTES); >>> if fNumBytes > 0 then // All read() calls will block, except the final >>> one. >> >> >> I am not sure this is always correct. Various versions of windows work >> differently in this regard; >> zero (0) may be a valid return value. I suggest you check >> fOurProcess.IsRunning to break the loop. > > Thank you, I will try it. But debugging I can see the problem is not > in the loop. In Windows XP fNumBytes is always zero: > > fNumBytes := fOurProcess.Output.Read((fMemStream.Memory + > fBytesRead)^, READ_BYTES); > > so it seems the Read of fOurProcess.Output is not giving the expected results. Read translates directly to a kernel call. > > In Windows 7 it's ok. Once more: Zero is a valid return value for read from a pipe. So it can perfectly be that read attempts 50 times returns 0, and only at read attempt 51 you get a positive result. That is why you must check isRunning, and not rely on the return value of readbytes.

It could also be due to the problem we detected in fpmkunit: If the stderr is a separate pipe and that pipe is full, the inferior will stop until that pipe is read.
See this patch:

http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-process/src/ process.pp?r1=29107&r2=29303

Could the difference between Windows 7 and Windows XP be related to different amount to stderr pipe?
Or maybe the internal pipe size is different?

In the hope this could be useful,

Pierre Muller

Reply by email

Antonio Sanguigni
to Michael Van Canneyt: Read translates directly to a kernel call. Once more: Zero is a valid return value for…
Show quoted text 8 lines
Once more: Zero is a valid return value for read from a pipe. So it can perfectly be that read attempts 50 times returns 0, and only at read attempt 51 you get a positive result. That is why you must check isRunning, and not rely on the return value of readbytes.

Thank you, this is my new code and while it's working good on Windows 7 it doesn't on Windows XP :(.

procedure TBurpClient.Run;
begin
  fOurProcess.Options := [poUsePipes] + [poNoConsole];
  fOurProcess.Execute;
  while fOurProcess.Running do
  begin
    // make sure we have room
    fMemStream.SetSize(fBytesRead + READ_BYTES);
    // try reading it
    fNumBytes := fOurProcess.Output.Read((fMemStream.Memory +
fBytesRead)^, READ_BYTES);
    Inc(fBytesRead, fNumBytes);
  end;
  fMemStream.SetSize(fBytesRead);
  fOutputLines := TStringList.Create;
  fOutputLines.LoadFromStream(fMemStream);
  fOutputLines.SaveToFile('output.txt');
  CommandOutput := fOutputLines.Text;
  faStringList.Assign(fOutputLines);
  fObjectList.Add(fOutputLines);
  Inc(fIndexOfOL);
  Inc(fIndexOfOL);
//  fOutputLines.Free;
end;
Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Michael Van Canneyt
to Antonio Sanguigni
Antonio Sanguigni wrote 15 lines
> Once more: > Zero is a valid return value for read from a pipe. > > So it can perfectly be that read attempts 50 times returns 0, and only at > read attempt 51 you get a positive result. > > That is why you must check isRunning, and not rely on the return value of > readbytes. Thank you, this is my new code and while it's working good on Windows 7 it doesn't on Windows XP :(. procedure TBurpClient.Run; begin fOurProcess.Options := [poUsePipes] + [poNoConsole];

Following the suggestion by Pierre:
Try adding [poStderrToOutPut] as well.

Michael.

Reply by email

Antonio Sanguigni
to Pierre Free Pascal: It could also be due to the problem we detected in fpmkunit: If the stderr is a separate…

2015-03-25 10:47 GMT+01:00 Pierre Free Pascal :

Show quoted text 7 lines
It could also be due to the problem we detected in fpmkunit: If the stderr is a separate pipe and that pipe is full, the inferior will stop until that pipe is read. See this patch: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-process/src/ process.pp?r1=29107&r2=29303

Thank you ! I just tried to add [poStderrToOutPut] as Michael adviced into Options but without result.

About your fpc patch, does it mean I will have to try download a svn checkout of fpc compiler and using that one instead of my actual packaged FPC 2.6.4 ?

Thank you
Antonio

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Graeme Geldenhuys
to Antonio Sanguigni: I know XP is an old OS but some customers of mine still have it ! I'm writing a little…
Antonio Sanguigni wrote
My problem is Windows XP I mean, the same code seems does not produce any results.

I've used the following code in fpGUI's demo IDE and it works here under FreeBSD, Linux and Win2000-Win7 (I don't have Win8 so can't test that).

The following code executes the FPC compiler an captures the results and triggers an event, which eventually displays the output in a message window.

=============================
procedure TBuilderThread.Execute;
const
  BufSize = 1024; //4096;
var
  p: TProcess;
  c: TfpgString;
  unitdir: TfpgString;
  Buf: string;
  Count: integer;
  i: integer;
  LineStart: integer;
begin
  unitdir := GProject.ProjectDir + GProject.UnitOutputDir;
  unitdir := GMacroList.ExpandMacro(unitdir);
  if not fpgDirectoryExists(unitdir) then
  begin
    {$IFDEF DEBUG}
    writeln('DEBUG:  TBuilderThread.Execute - Creating dir: ' + unitdir);
    {$ENDIF}
    fpgForceDirectories(unitDir);
  end;
  p := TProcess.Create(nil);
  p.Options := [poUsePipes, poStdErrToOutPut];
  p.ShowWindow := swoShowNormal;
  p.CurrentDirectory := GProject.ProjectDir;
  // build compilation string
  c := gINI.ReadString(cEnvironment, 'Compiler', '');
  c := c + GProject.GenerateCmdLine(False, BuildMode);
  c := GMacroList.ExpandMacro(c);
//  AddMessage('Compile command: ' + c);
  p.CommandLine := c;
  try
    p.Execute;
    { Now process the output }
    OutputLine:='';
    SetLength(Buf,BufSize);
    repeat
      if (p.Outputnil) 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);
          Synchronize(@DoOutputLine);
          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
      Synchronize(@DoOutputLine);
    p.WaitOnExit;
  finally
    FreeAndNil(p);
  end;
end;
=============================

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Antonio Sanguigni
to Graeme Geldenhuys

2015-03-25 12:56 GMT+01:00 Graeme Geldenhuys :

Show quoted text 5 lines
I've used the following code in fpGUI's demo IDE and it works here under FreeBSD, Linux and Win2000-Win7 (I don't have Win8 so can't test that). The following code executes the FPC compiler an captures the results and triggers an event, which eventually displays the output in a message window.

Thanks Graeme, works well ... in Windows 7 here. Same code in Windows XP nothing to do. :O

Antonio

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Pierre Free Pascal
to Antonio Sanguigni

Are you sure that it is not specific to the executable that you run?

Did you try if redirecting the output of this executable to a file using simply Windows Console
executable.exe all args > outfile.txt

you get the same results on Windows XP as on Windows 7?

Pierre Muller

Show quoted text 35 lines
-----Message d'origine----- De : [mailto:fpc-pascal- De la part de Antonio Sanguigni Envoyé : mercredi 25 mars 2015 15:43 À : FPC-Pascal users discussions Objet : Re: [fpc-pascal] TProcess does not work in Windows XP 2015-03-25 12:56 GMT+01:00 Graeme Geldenhuys : > I've used the following code in fpGUI's demo IDE and it works here under > FreeBSD, Linux and Win2000-Win7 (I don't have Win8 so can't test that). > > The following code executes the FPC compiler an captures the results and > triggers an event, which eventually displays the output in a message window. Thanks Graeme, works well ... in Windows 7 here. Same code in Windows XP nothing to do. :O Antonio -- Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Antonio Sanguigni
to Pierre Free Pascal

2015-03-25 17:15 GMT+01:00 Pierre Free Pascal :

Show quoted text 7 lines
Are you sure that it is not specific to the executable that you run? Did you try if redirecting the output of this executable to a file using simply Windows Console executable.exe all args > outfile.txt you get the same results on Windows XP as on Windows 7?

aaargh !! Thank you Pierre, I did not try that.

I just watched at the console output. Redirecting the pipe shows command output on windows 7 output.txt and a blank output.txt in windows xp ! I will write to developer list, then !

Sorry to bother all you.

Antonio

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email

Graeme Geldenhuys
to Antonio Sanguigni: 2015-03-25 12:56 GMT+01:00 Graeme Geldenhuys : Thanks Graeme, works well ... in Windows 7…
Antonio Sanguigni wrote
Thanks Graeme, works well ... in Windows 7 here. Same code in Windows XP nothing to do. :O

I'm affair there must be something weird in your WinXP setup then. I just tested again using WinXP and Maximus IDE (which uses the exact code I posted earlier). Attached is a screenshot showing the compiler output in the Messages window - read from TProcess.

As I mentioned, that code works on Win2000 all the way to Win7 (and probably Win8 too), plus FreeBSD and Linux.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Antonio Sanguigni
to Graeme Geldenhuys

2015-03-25 17:26 GMT+01:00 Graeme Geldenhuys :

Show quoted text 9 lines
On 2015-03-25 14:42, Antonio Sanguigni wrote: I'm affair there must be something weird in your WinXP setup then. I just tested again using WinXP and Maximus IDE (which uses the exact code I posted earlier). Attached is a screenshot showing the compiler output in the Messages window - read from TProcess. As I mentioned, that code works on Win2000 all the way to Win7 (and probably Win8 too), plus FreeBSD and Linux.

Sure Graeme, at this point I think you are right. I will try to get another windows XP box to test deeply.

Thank you
Antonio

Antonio Sanguigni alias slapshot ---------------------------------------------------------------------- Servizi informatici Windows e GNU/Linux- http://www.pieroni.biz GioveLUG (Linux User Group) - http://www.giovelug.org

Reply by email