Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как вывести данные не в консоль (cmd), а в TMemo?

Delphi , ОС и Железо , DOS и Консоль

Вариант 1

Код взят из http://www.torry.net/memos.htm

Code:

procedure Dos2Win(CmdLine:String; OutMemo:TMemo);
const BUFSIZE = 2000;
var SecAttr    : TSecurityAttributes;
   hReadPipe,
   hWritePipe : THandle;
   StartupInfo: TStartUpInfo;
   ProcessInfo: TProcessInformation;
   Buffer     : Pchar;
   WaitReason,
   BytesRead  : DWord;
begin
 
with SecAttr do
begin
  nlength              := SizeOf(TSecurityAttributes);
  binherithandle       := true;
  lpsecuritydescriptor := nil;
end;
// Creazione della pipe
if Createpipe (hReadPipe, hWritePipe, @SecAttr, 0) then
begin
  Buffer  := AllocMem(BUFSIZE + 1);    // Allochiamo un buffer di dimensioni BUFSIZE+1
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb          := SizeOf(StartupInfo);
  StartupInfo.hStdOutput  := hWritePipe;
  StartupInfo.hStdInput   := hReadPipe;
  StartupInfo.dwFlags     := STARTF_USESTDHANDLES +
                             STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_HIDE;
 
 if CreateProcess(nil,
     PChar(CmdLine),
     @SecAttr,
     @SecAttr,
     true,
     NORMAL_PRIORITY_CLASS,
     nil,
     nil,
     StartupInfo,
     ProcessInfo) then
    begin
      // Attendiamo la fine dell'esecuzione del processo
      repeat
        WaitReason := WaitForSingleObject( ProcessInfo.hProcess,100);
        Application.ProcessMessages;
      until (WaitReason <> WAIT_TIMEOUT);
      // Leggiamo la pipe
      Repeat
        BytesRead := 0;
        // Leggiamo "BUFSIZE" bytes dalla pipe
        ReadFile(hReadPipe, Buffer[0], BUFSIZE, BytesRead, nil);
        // Convertiamo in una stringa " terminated"
        Buffer[BytesRead]:= #0;
        // Convertiamo i caratteri da DOS ad ANSI
        OemToAnsi(Buffer,Buffer);
        // Scriviamo nell' "OutMemo" l'output ricevuto tramite pipe
        OutMemo.Text := OutMemo.text + String(Buffer);
      until (BytesRead < BUFSIZE);
    end;
  FreeMem(Buffer);
  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ProcessInfo.hThread);
  CloseHandle(hReadPipe);
  CloseHandle(hWritePipe);
end;
end;
 


Взято с Vingrad.ru http://forum.vingrad.ru


Вариант 2:

А это исправленный Song'ом вариант для обеспечения вывода текста в real-time


Вариант 3:

Автор: Алексей Бойко

Это пример запуска консольных программ с передачей ей консольного ввода (как если бы он был введен с клавиатуры после запуска программы) и чтением консольного вывода. Таким способом можно запускать например стандартный виндовый ftp.exe (в невидимом окне) и тем самым отказаться от использования специализированных, зачастую глючных компонент.

Code:

function ExecuteFile(FileName,StdInput: string;
                    TimeOut: integer;
                    var StdOutput:string) : boolean;
 
label Error;
 
type
TPipeHandles = (IN_WRITE,  IN_READ,
                 OUT_WRITE, OUT_READ,
                 ERR_WRITE, ERR_READ);
 
type
TPipeArray = array [TPipeHandles] of THandle;
 
var
i         : integer;
ph        : TPipeHandles;
sa        : TSecurityAttributes;
Pipes     : TPipeArray;
StartInf  : TStartupInfo;
ProcInf   : TProcessInformation;
Buf       : array[0..1024] of byte;
TimeStart : TDateTime;
 
 
function ReadOutput : string;
var
i : integer;
s : string;
BytesRead : longint;
 
begin
Result := '';
repeat
 
   Buf[0]:=26;
   WriteFile(Pipes[OUT_WRITE],Buf,1,BytesRead,nil);
   if ReadFile(Pipes[OUT_READ],Buf,1024,BytesRead,nil) then
   begin
     if BytesRead>0 then
     begin
       buf[BytesRead]:=0;
       s := StrPas(@Buf[0]);
       i := Pos(#26,s);
       if i>0 then s := copy(s,1,i-1);
       Result := Result + s;
     end;
   end;
 
   if BytesRead1024 then break;
until false;
end;
 
 
begin
Result := false;
for ph := Low(TPipeHandles) to High(TPipeHandles) do
   Pipes[ph] := INVALID_HANDLE_VALUE;
 
 
// Создаем пайпы
sa.nLength := sizeof(sa);
sa.bInheritHandle := TRUE;
sa.lpSecurityDescriptor := nil;
 
 
if not CreatePipe(Pipes[IN_READ],Pipes[IN_WRITE], @sa, 0 ) then
   goto Error;
if not CreatePipe(Pipes[OUT_READ],Pipes[OUT_WRITE], @sa, 0 ) then
   goto Error;
if not CreatePipe(Pipes[ERR_READ],Pipes[ERR_WRITE], @sa, 0 ) then
   goto Error;
 
 
 
// Пишем StdIn
StrPCopy(@Buf[0],stdInput+^Z);
WriteFile(Pipes[IN_WRITE],Buf,Length(stdInput),i,nil);
 
 
// Хендл записи в StdIn надо закрыть - иначе выполняемая программа
// может не прочитать или прочитать не весь StdIn.
 
CloseHandle(Pipes[IN_WRITE]);
 
Pipes[IN_WRITE] := INVALID_HANDLE_VALUE;
 
 
FillChar(StartInf,sizeof(TStartupInfo),0);
StartInf.cb := sizeof(TStartupInfo);
StartInf.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
 
 
StartInf.wShowWindow := SW_SHOW; // SW_HIDE если надо запустить невидимо
 
 
StartInf.hStdInput := Pipes[IN_READ];
StartInf.hStdOutput := Pipes[OUT_WRITE];
StartInf.hStdError := Pipes[ERR_WRITE];
 
 
if not CreateProcess(nil, PChar(FileName), nil,
                      nil, True, NORMAL_PRIORITY_CLASS,
                      nil, nil, StartInf, ProcInf) then goto Error;
 
TimeStart := Now;
 
repeat
   Application.ProcessMessages;
   i := WaitForSingleObject(ProcInf.hProcess,100);
   if i = WAIT_OBJECT_0 then break;
   if (Now-TimeStart)*SecsPerDay>TimeOut then break;
until false;
 
 
if iWAIT_OBJECT_0 then goto Error;
StdOutput := ReadOutput;
 
for ph := Low(TPipeHandles) to High(TPipeHandles) do
   if Pipes[ph]INVALID_HANDLE_VALUE then
     CloseHandle(Pipes[ph]);
 
 
CloseHandle(ProcInf.hProcess);
CloseHandle(ProcInf.hThread);
Result := true;
Exit;
 
 
Error:
 
if ProcInf.hProcessINVALID_HANDLE_VALUE then
 
begin
   CloseHandle(ProcInf.hThread);
   i := WaitForSingleObject(ProcInf.hProcess, 1000);
   CloseHandle(ProcInf.hProcess);
   if iWAIT_OBJECT_0 then
 
   begin
     ProcInf.hProcess := OpenProcess(PROCESS_TERMINATE,
                                     FALSE,
                                     ProcInf.dwProcessId);
 
     if ProcInf.hProcess  0 then
     begin
       TerminateProcess(ProcInf.hProcess, 0);
       CloseHandle(ProcInf.hProcess);
     end;
   end;
end;
 
for ph := Low(TPipeHandles) to High(TPipeHandles) do
   if Pipes[ph]INVALID_HANDLE_VALUE then
     CloseHandle(Pipes[ph]);
 
end;
 


Взято из http://forum.sources.ru

Это код на языке Delphi, который запускает консольное приложение и захватывает его вывод в реальном времени, без отображения окна консоли.

Первый вариант (Dos2Win) создает трубу и использует ее для общения с процессом-ребенком (консольным приложением). Функция CreateProcess используется для создания процесса-ребенка, а функция ReadFile - для чтения из трубы. Вывод процесса-ребенка записывается в компонент мемо.

Второй вариант (ExecuteFile) - улучшенная версия, которая включает обработку ошибок и позволяет захватывать вывод в реальном времени.

Схема кода следующая:

  1. Первый раздел определяет типы и переменные, используемые в коде.
  2. Функция ReadOutput читает из трубы и конвертирует вывод в строку.
  3. Главная процедура создает трубы, пишет в стандартный ввод (если предоставлен), и запускает процесс-ребенка с помощью CreateProcess.
  4. Код ждет, пока процесс-ребенок не закончится, используя WaitForSingleObject. Если таймаут достигнут, код прерывает процесс-ребенка с помощью TerminateProcess.
  5. Вывод процесса-ребенка читается из трубы с помощью ReadFile и хранится в строке.
  6. Наконец, код закрывает все handles и возвращает результат.

Третий вариант (ExecuteFile) добавляет дополнительную обработку ошибок и позволяет захватывать вывод в реальном времени, читая из трубы маленькими кусками (1024 байта за раз).

В целом, этот код предоставляет способ запускать консольные приложения программно в Delphi без отображения окна консоли.

Данные выводятся в TMemo с помощью метода Text := OutMemo.text + String(Buffer).


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: DOS и Консоль ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 12:26:30/0.0044910907745361/0