www.demi-s.narod.ru

Delphi
Статьи:

· Интерфейс

· WinAPI

· Компоненты

· Базы данных

· ShellAPI



WinAPI


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

В предыдущей статье было описано, как перехватить вывод из 32-разрядного консольного приложения. Как это сделать с 16-разрядным приложением?

Есть новая функция. Это обходит проблему с 16-разрядными приложениями. Будьте осторожны при вызове command.com, так как мы ожидаем окончания процесса, а command.com ждет ввода пользователя...

function GetConsoleOutput(const CommandLine: string): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutFile, AppProcess, AppThread : THandle;
  RootDir, WorkDir, StdOutFileName:string;
const
  FUNC_NAME = 'GetConsoleOuput';
begin
  try
    StdOutFile:=0;
    AppProcess:=0;
    AppThread:=0;
    Result:='';

    // инициализируем каталог
    RootDir:=ExtractFilePath(ParamStr(0));
    WorkDir:=ExtractFilePath(CommandLine);

    // проверяем WorkDir
    if not (FileSearch(ExtractFileName(CommandLine),WorkDir) <> '') then
WorkDir:=RootDir;

   // инициализируем атрибуты защиты файла вывода
    FillChar(SA,SizeOf(SA),#0);
    SA.nLength:=SizeOf(SA);
    SA.lpSecurityDescriptor:= nil;
    SA.bInheritHandle:= True;

    // Создаем файл вывода
    StdOutFileName:= RootDir + 'output.tmp';
    StdOutFile:=CreateFile(PChar(StdOutFileName),
                   GENERIC_READ or GENERIC_WRITE,
                   FILE_SHARE_READ or FILE_SHARE_WRITE,
                   @SA,
                   CREATE_ALWAYS, // всегда создавать его
                   FILE_ATTRIBUTE_TEMPORARY or // Будет кэш в памяти,
                                               // если возможно
                   FILE_FLAG_WRITE_THROUGH,
                   0);

    // Проверяем дескриптор вывода
    if StdOutFile = INVALID_HANDLE_VALUE then
      raise Exception.CreateFmt('Function %s() failed!' + #10#13 +
        'Command line = %s', [FUNC_NAME,CommandLine]);

    // инициализируем Startup Info
    FillChar(SI, SizeOf(SI), #0);
    with SI do begin
      cb:= SizeOf(SI);
      dwFlags:= STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow:= SW_HIDE;
      hStdInput:= GetStdHandle(STD_INPUT_HANDLE);
      hStdError:= StdOutFile;
      hStdOutput:= StdOutFile;
    end;

    // Создаем процесс
    if CreateProcess(nil>, PChar(CommandLine), nil, nil, 
                     True, 0, nil,
                     PChar(WorkDir), SI, PI) then begin
      WaitForSingleObject(PI.hProcess,INFINITE);
      AppProcess:= PI.hProcess;
      AppThread:= PI.hThread;
      end
    else
      raise Exception.CreateFmt('CreateProcess() in function %s() failed!'
                   + #10#13 + 'Command line = %s', [FUNC_NAME, CommandLine]); 

    CloseHandle(StdOutFile);
    StdOutFile:=0;

    with TStringList.Create do
    try
      LoadFromFile(StdOutFileName);
      Result:= Text;
    finally
      Free;
    end;

  finally
    // Закрываем дескрипторы
    if StdOutFile <> 0 then CloseHandle(StdOutFile);
    if AppProcess <> 0 then CloseHandle(AppProcess);
    if AppThread <> 0 then CloseHandle(AppThread);

    // Удаляем файл вывода
    if FileExists(StdOutFileName) then DeleteFile(StdOutFileName);
  end;

end;

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


Hosted by uCoz