Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Запуск внешнего приложения


Автор: deadsy 25.6.2004, 09:04
Есть некая консольная утилита, надо к ней написать GUI. Эта утилита делает довольно длительную обработку данных и выводит в консоль процент выполнения. В связи с такой задачей возникают вопросы:

1. Как запустить такую утилиту (ShellExecute,CreateProcess) чтобы можно было:
2. Скрыть окно консоли в котором она работает и
3. Перенаправить вывод консоли в своё приложение ну и читать данные (ну чтобы прогрессбар там сделать хотя-бы).

Автор: Alex 25.6.2004, 13:48
Код
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); // стандартный ввод не перенаправляем
     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.


Взято с Исходников.ru http://www.sources.ru

Автор: h2o 22.8.2005, 16:03
Работоспособности добиться не удалось... у кого-нибудь хоть получилось???

Где в этой проге что запускается (мне к примеру winrar нужно запустить)????

И где в этой проге вывод? Точнее куда всё выводится??? Куда???

Автор: _hunter 22.8.2005, 16:35
в пайп. там же все написанно...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)