Newsgroup: it.comp.lang.delphi
Titolo: Eseguire un'applicazione esterna

Ho la necessità di eseguire un'applicazione dos da un programma
Delphi(...3.0). Questa applicazione dos ha dei parametri e restituisce un
output sulla shell. Come faccio ad intercettare questo output e a
ridirezionarlo su un file ASCII o binario?
Se utilizzo l'API:
            ShellExecute(Handle, Null, 'fdls', 'a: > scr', work_dir,
SW_SHOW);
(dove fdls è l'applicazione dos ed scr è l'ipotetico file su cui
ridirezionare l'output)
l'applicazione dos viene eseguita ma non riottengo il ridirezionamento dei
dati su scr (..da linea di comando invece funziona perfettamente). Sono
disperato, vi prego aiutatemi altrimenti mi suiciderò presto perchè non mi
viene in mente nessuna soluzione!
Grazie...

 SW_SHOW);
Non so se si possa fare con ShellExecute, ma lo puoi sicuramente fare con
CreateProcess. il seguente codice e' preso dal componente TAppExec di
Patrick Brisacier e Jean-Fabien Connault, leggermente modificato da me
appunto per gestire la redirezione.
Puoi vedere le righe
  StartupInfo.hStdInput:=input;
  StartupInfo.hStdOutput:=output;
  StartupInfo.hStdError:=error;
qui vanno passati 3 handle a risorse di Windows. per fare in modo che usi i
file puoi fare:
var x:TFileStream;
x:=TFileStream.create('output.txt');
StartupInfo.hStdOutput:=x.handle;
e lo stesso per le altre 2 (eventualmente puoi usare un solo file per output
e error)
Ciao !!                        {MSX}
Ecco il codice
  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.hStdInput:=input;
  StartupInfo.hStdOutput:=output;
  StartupInfo.hStdError:=error;
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  StartupInfo.wShowWindow := FMode;
  if not CreateProcess(nil,
    buffer,                        { pointer to command line string }
    nil,                           { pointer to process security
attributes }
    nil,                           { pointer to thread security attributes }
    false,                         { handle inheritance flag }
    CREATE_NEW_CONSOLE or          { creation flags }
    NORMAL_PRIORITY_CLASS,
    nil,                           { pointer to new environment block }
    nil,                           { pointer to current directory name }
    StartupInfo,                   { pointer to STARTUPINFO }
    ProcessInfo) then begin        { pointer to PROCESS_INF }
    FErrNo := GetLastError();
    raise EAppExecWinExec.Create(GetErrorString);
  end

confermo, anche secondo me bisogna usare la create process, solo che se non
ricordo male avevo qualche problema con waitforsingleobject.....
--
Consonni Davide
bmq...@tin.it
gna...@wappi.com
webmaster of
http://gnaffy.Tripod.com
http://www.traduzioniellepi.com

dati su scr (..da linea di comando invece funziona perfettamente). 
Infatti, perche' il nuovo indirizzamento e' un'interpretazione della
shell, non dell'applicazione.
La soluzione e' relativamente semplice e prende spunto dal modello di
gestione delle pipe di Unix.
La routine seguente (che gira sotto WindowsNT 4.0 Workstation) fa
parte di un programma dimostrativo che presto mettero' sul mio sito (e
che se vuoi ti spedisco per e-mail).
Stai attento ad aggiungere i controlli d'errore (omessi per rendere il
codice + semplice) in prossimita' di tutte le API Create* :
procedure TForm1.btnExecuteChildProcessClick(Sender: TObject);
var InputHandle, OutputHandle : array [0..1] of THandle ;
    SI : TStartupInfo ;
    PI : TProcessInformation ;
    SA : TSecurityAttributes ;
    ChildOutput : array [ byte ] of char ;
    nReadChars : DWORD ;
begin
  if ( edtChildProcessName.Text = '' ) then
    MessageDlg( 'Nessun file eseguibile specificato!', 
                mtWarning,  [mbOk], 0 )
  else
  begin
    mChildOutput.Lines.Clear ;
    ZeroMemory( @SA, SizeOf( SA ) ) ;
    ZeroMemory( @SI, SizeOf( SI ) ) ;
    SA.nLength := SizeOf( SA ) ;
    SA.bInheritHandle := true ;
    SI.cb := SizeOf( SI ) ;
    CreatePipe( InputHandle[0], InputHandle[1], @SA, 0 ) ;
    CreatePipe( OutputHandle[0], OutputHandle[1], @SA, 0 ) ;
    SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW ;
    SI.wShowWindow := SW_HIDE ;
    SI.hStdOutput := OutputHandle[1] ;
    SI.hStdError := OutputHandle[1] ;
    SI.hStdInput := InputHandle[0] ;
    CreateProcess( nil, PChar( edtChildProcessName.Text ),
                   nil, nil, true, 0,
                   nil, nil, SI, PI ) ;
    CloseHandle( OutputHandle[1] ) ;
    CloseHandle( InputHandle[0] ) ;
    while( ReadFile( OutputHandle[0], ChildOutput, 
                     SizeOf( ChildOutput),
                     nReadChars, nil ) and ( nReadChars > 0 ) ) do
    begin
      mChildOutput.Lines.Add( ChildOutput ) ;
    end ;
    CloseHandle( OutputHandle[0] ) ;
  end ;
end ;
--
Andrea Laforgia (ICQ 87230455)
http://www.geocities.com/AndreaLaforgia
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."