[Delphi]取得執行dos App後的結果(參考http://www.delphi3000.com/articles/article_3361.asp)

[Delphi]取得執行dos App後的結果(參考http://www.delphi3000.com/articles/article_3361.asp)

image

image

   1:  procedure TForm1.btnExecuteClick(Sender: TObject);
   2:    procedure CaptureConsoleOutput(DosApp : string;AMemo : TMemo);
   3:    const
   4:      ReadBuffer = 1048576;  // 1 MB Buffer
   5:    var 
   6:      Security            : TSecurityAttributes;
   7:      ReadPipe,WritePipe  : THandle;
   8:      start               : TStartUpInfo;
   9:      ProcessInfo         : TProcessInformation; 
  10:      Buffer              : Pchar;
  11:      TotalBytesRead, 
  12:      BytesRead           : DWORD;
  13:      Apprunning,n, 
  14:      BytesLeftThisMessage,
  15:      TotalBytesAvail : integer;
  16:    begin 
  17:      with Security do
  18:      begin
  19:        nlength              := SizeOf(TSecurityAttributes);
  20:        binherithandle       := true;
  21:        lpsecuritydescriptor := nil; 
  22:      end; 
  23:   
  24:      if CreatePipe (ReadPipe, WritePipe, @Security, 0) then
  25:      begin 
  26:        // Redirect In- and Output through STARTUPINFO structure
  27:   
  28:        Buffer  := AllocMem(ReadBuffer + 1); 
  29:        FillChar(Start,Sizeof(Start),#0);
  30:        start.cb          := SizeOf(start); 
  31:        start.hStdOutput  := WritePipe; 
  32:        start.hStdInput   := ReadPipe;
  33:        start.dwFlags     := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; 
  34:        start.wShowWindow := SW_HIDE; 
  35:   
  36:        // Create a Console Child Process with redirected input and output
  37:   
  38:        if CreateProcess(nil      ,PChar(DosApp), 
  39:                         @Security,@Security, 
  40:                         true     ,CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,
  41:                         nil      ,nil, 
  42:                         start    ,ProcessInfo) then 
  43:        begin 
  44:          n:=0;
  45:          TotalBytesRead:=0; 
  46:          repeat 
  47:            // Increase counter to prevent an endless loop if the process is dead 
  48:            Inc(n,1);
  49:           
  50:            // wait for end of child process 
  51:            Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100); 
  52:            Application.ProcessMessages;
  53:   
  54:            // it is important to read from time to time the output information
  55:            // so that the pipe is not blocked by an overflow. New information
  56:            // can be written from the console app to the pipe only if there is
  57:            // enough buffer space.
  58:   
  59:            if not PeekNamedPipe(ReadPipe        ,@Buffer[TotalBytesRead], 
  60:                                 ReadBuffer      ,@BytesRead,
  61:                                 @TotalBytesAvail,@BytesLeftThisMessage) then break
  62:            else if BytesRead > 0 then 
  63:              ReadFile(ReadPipe,Buffer[TotalBytesRead],BytesRead,BytesRead,nil);
  64:            TotalBytesRead:=TotalBytesRead+BytesRead; 
  65:          until (Apprunning <> WAIT_TIMEOUT) or (n > 150);
  66:   
  67:          Buffer[TotalBytesRead]:= #0;
  68:          OemToChar(Buffer,Buffer);
  69:          AMemo.Text := AMemo.text + StrPas(Buffer); 
  70:        end;
  71:        FreeMem(Buffer);
  72:        CloseHandle(ProcessInfo.hProcess);
  73:        CloseHandle(ProcessInfo.hThread);
  74:        CloseHandle(ReadPipe);
  75:        CloseHandle(WritePipe);
  76:      end;
  77:    end;
  78:  begin
  79:    mmo1.Clear;
  80:    CaptureConsoleOutput(edtdir.Text, mmo1);
  81:  end;

image image