On 08/05/11 05:38, Anton Shepelev wrote:
Hello all,

I  have been experimenting with redirection of stan-
dard I/O of child processes using  FreePascal  2.4.2
on  Windows.  I have succeeded in capturing standard
input and standard output, but failed to feed my own
data to the child's standard input.

The  child process doesn't seem to receive any input
at all, staying blocked forever.

At first I thought it was a problem with my usage of
WinApi,  so  I rewrote my program using the TProcess
class... just to get the same  result.  The  program
feeds  'Anton'  to the more.com program and captures
part of its output:

Program StrRedir;
uses Classes, Process, Sysutils;
const MaxByte = 255;
type
       TStrBuf = packed record {As a way to read buffers into strings}
       case Boolean of
          true: (  size: Byte;
                   buf:  array[0..MaxByte] of Char;
                );
          false:(  txt:  ShortString;  );
       end;

var
    MoreProcess: TProcess;
    readCount:   integer;
    strBuf:      TStrBuf;

begin
    MoreProcess := TProcess.Create(nil);
    MoreProcess.CommandLine := 'C:\WINDOWS\system32\cmd.exe /C more';
    MoreProcess.Options := [poUsePipes];
    MoreProcess.Execute;
    strBuf.txt := 'Anton';
    MoreProcess.Input.Write(strBuf.buf, strBuf.size);
    MoreProcess.CloseInput();
    writeLn('Waiting...');    //This never ends
    while MoreProcess.Running do begin Sleep(50); end;
    writeLn('Wait finished.');
    Sleep(100);
    strBuf.size := MoreProcess.Output.Read(strBuf.buf, 255);
    writeLn(strBuf.txt);
end.

Could you please help me to make it work?

Thanks in advance,
Anton

Anton - I have attached an extract from some working code (hopefully I didnt remove anything necessary)
It may help you move on a bit further

SteveG




    Process.Execute

    // capture all proc output (if required) - watch for proc ending quickly, 
but data still waiting
    while ( Process.Running )                                                   
                                                // cycle whilst process active
    OR    ( (poUsePipes IN Process.Options) AND 
(Process.Output.NumBytesAvailable > 0) )                                        
// OR finished already, still data waiting
    do begin
      Sleep(1);

      if Terminated then break;

      // no pipes - not past here as causes exceptions to read process pipes if 
not enabled
      if NOT (poUsePipes IN Process.Options) then continue;

      // read output
      BytesAvailable := Process.Output.NumBytesAvailable;
      if BytesAvailable > 0 then begin
        SetLength(str1, BytesAvailable);
        Process.OutPut.Read(str1[1], BytesAvailable);
        StdOutStore += str1;
      end;

      // read errors
      BytesAvailable := Process.Stderr.NumBytesAvailable;
      if BytesAvailable > 0 then begin
        SetLength(str1, BytesAvailable);
        Process.Stderr.Read(str1[1], BytesAvailable);
        StdErrStore += str1;
      end;

      // send input
      if UsrSendMsg > '' then begin
        Process.Input.Write(UsrSendMsg[1], Length(UsrSendMsg));
        UsrSendMsg := '';
      end;

    end;
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to