www.demi-s.narod.ru

Delphi
Статьи:

· Интерфейс

· WinAPI

· Компоненты

· Базы данных

· ShellAPI



WinAPI


Захват всех выводов из консольного приложения

Используйте функцию GetDosOutput в Вашем приложении, чтобы захватить все выводы из приложения DOS (эта версия поддерживает только 32-разрядные консольные приложения. Чтобы узнать, как это делать с 16-разрядными консольными приложениями, смотри в следующей статье

unit consoleoutput;

interface

uses
  Controls, Windows, SysUtils, Forms;

function GetDosOutput(const CommandLine: string): string;

implementation

function GetDosOutput(const CommandLine: string): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of Char;
  BytesRead: Cardinal;
  WorkDir, Line: String;
begin
  Application.ProcessMessages;
  with SA do
  begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  // создаем канал для переназначения стандартного вывода
  CreatePipe(StdOutPipeRead,  // читаем дескриптор
             StdOutPipeWrite, // записываем дескриптор
             @SA,             // атрибуты безопасности
             0                // кол-во байт, зарезервированных для канала - 0 
по умолчанию
             ); 
  try
    //  Заставим дочерний процесс использовать StdOutPipeWrite как стандартный вывод,
    // и удостоверимся, что это не отображается на экране
    with SI do
    begin
      FillChar(SI, SizeOf(SI), 0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // не переадресовывать std
ввод
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;

    // запускаем компилятор командной строки
    WorkDir := ExtractFilePath(CommandLine);
    WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, 
PChar(WorkDir), SI, PI);

    // Теперь, когда дескриптор был унаследован, закройте запись для безопасности.
    CloseHandle(StdOutPipeWrite); 
    if not WasOK then
      raise Exception.Create('Could not execute command line!')
    else
      try
        // получать все выводы, пока приложение dos не закончится
        Line := '';
        repeat
          // читаем блок символов (может содержать перевод каретки и перевод строки)
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil); 

          // что-нибудь прочитали?
          if BytesRead > 0 then
          begin
            // конец буфера PChar
            Buffer[BytesRead] := #0;
            // объединяем буфер с остальной частью
            Line := Line + Buffer;
          end;
        until not WasOK or (BytesRead = 0);
        // ждем окончания работы консольного приложения
        WaitForSingleObject(PI.hProcess, INFINITE);
      finally
        // закроем все остальные дескрипторы
        CloseHandle(PI.hThread);
        CloseHandle(PI.hProcess);
      end;
  finally
      result:=Line;
      CloseHandle(StdOutPipeRead);
  end;
end;

end.

Если Вы хотите использовать параметры, можно сделать так:

Params := ExeFile + ' ' + Params; 
    WasOK := CreateProcess(PChar(ExeFile), PChar(Params), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI); 
	

Внимание: не тестировалось на совместимость с XP!

Источник: www.delphi3000.com


Hosted by uCoz