Newsgroup: it.comp.lang.delphi
Titolo: interprocess communication

dovrei scrivere un programmino che istanzia un processo passandogli come
parametro il nome di un file.exe e che comunica con esso mediante pipe di
stdout e stderr,
 qualcuno sa come fare e quali api richiamare?
grazie
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

comincia dal cercare:
Process and Thread Functions
nella guida sdk di windows fornita con delphi
Poi, puoi vedere mutex e mailslot.
Bye
A

 grazie
Essenzialmente bastano CreateProcess, CreatePipe, ReadFile e WriteFile.
Se il processo che parte non ha bisogno di input (gli bastano i
parametri) la seguente funzione e' sufficiente (RaiseWinErr va
sostituito da qualcosa tipo RaiseLastSystemError).
Aggiungo anche un pezzo del thread che si occupa di ricevere l'output
del processo lanciato e che a sua volta lo trasmette alla form
principale con messaggi.
Saluti
Paolo Arosio
var si: TStartupInfo;
    pi: TProcessInformation;
    sa: TSecurityAttributes;
    inP,
    outP: array[0..1] of THandle;  // handle for Pipes
procedure TfrmMain.ExecuteWithRedir(ExePath: string; ParamStrings:
TStrings);
var AppName, CmdLine: string;
    i: integer;
begin
  AppName := ExePath;
  CmdLine := ' ';
  for i := 0 to Pred(ParamStrings.Count) do begin
    CmdLine := CmdLine + ' ' + ParamStrings[i];
  end;
  CmdLine := AppName + CmdLine;
  FillChar(sa, sizeof(sa), 0);
  sa.nLength := sizeof(sa);
  sa.bInheritHandle := True;
  if not(CreatePipe(outP[0], outP[1], @sa, 0)) then
    RaiseWinErr;
  try
    if not(CreatePipe(inP[0], inP[1], @sa, 0)) then
      RaiseWinErr;
    try
      FillChar(si, sizeof(si), 0);
      si.cb := sizeof(si);
      si.dwFlags :=  STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
      si.wShowWindow := SW_HIDE;
      si.hStdError := outP[1];
      si.hStdOutput := si.hStdError;
      si.hStdInput := inP[0];
      if not (CreateProcess(nil, PChar(CmdLine), nil, nil, True, 0, nil,
nil, si, pi)) then
        RaiseWinErr;
    except
      closeHandle(inP[0]);
      closeHandle(inP[1]);
      raise;
    end;
  except
    closeHandle(outP[0]);
    closeHandle(outP[1]);
    raise;
  end;
   // Chiude i lati che non servono piu`
  CloseHandle(outP[1]);
  CloseHandle(inP[0]);
  TheReader := TListener.Create(outP[0]); // chiusura della pipe in
wmDataReady
end;
type
  TListener = class(TThread)
    FPipe2Read: THandle;
  private     { Private declarations }
  protected
    procedure Execute; override;
    procedure NotifyError;
  public
    constructor Create(Pipe2Read: THandle);
    destructor Destroy; override;
  end;
....
procedure TListener.Execute;
var buf: array[0..MAX_BUF_SIZE] of char;
    nread: cardinal;
  procedure PostMainMsg(Msg: PChar; len: integer);
  var
    MsgStr: PShortString;
  begin
    if len = 0 then
      PostMessage(frmMain.Handle, WM_DATA_READY, 0, 0)
    else begin
      OutputDebugString(Msg);
      New(MsgStr);                        // freed in frmMain msg
handler
      MsgStr^ := Msg;
      MsgStr^[len+1] := #0;               // !!
      PostMessage(frmMain.Handle, WM_DATA_READY, len, Integer(MsgStr));
      sleep(5);                           // ??
    end;
  end;
begin
  { Place thread code here }
  try
    while not Terminated do begin
      FillChar(buf, sizeof(buf), #0);
      if not ReadFile(FPipe2Read, buf, sizeof(buf)-1, nread, nil) then
begin
        // end of file or error
        PostMessage(frmMain.Handle, WM_DATA_READY, 0, GetLastError);
        Break;  // terminate cycle
        //--  Synchronize(NotifyError); NOBBUONO
      end
      else if nread > 0 then begin
        PostMainMsg(@buf[0], nread);
      end;
    end;
  except
  end;
end;