Есть методы перехвата консольного ввода-вывода и есть методы инкапсуляции реальной консоли.
Первые отлично работают, но полностью адекватного эмулятора терминала я так и не нашел и то что я вижу в "эмуляторе терминала" часто совершенно не похоже на то что видно в реальной консоле.
Вторые могут нормально отображать вывод консольной программы но я совершенно не имею доступа выводу, а его желательно как-то парсить .
Отсюда вопрос: как добраться до консольного "тестового буфера" и прочитать то что в нем находится или просто дублировать захваченный вывод обратно в консоль
 
 Захват консоли
- Код: Выделить всё
- Procedure RunDosInMemo(CmdLine: String; AMemo: TMemo);
 Const
 ReadBuffer = 1023;
 Var
 Security: TSecurityAttributes;
 OutReadPipe, OutWritePipe: tHandle; // труба для output'a консольной проги.
 InReadPipe, InWritePipe: tHandle; // труба для input'a консольной проги.
 ErrReadPipe, ErrWritePipe: tHandle; // труба для error's консольной проги.
 // InReadPipe, ErrReadPipe и объявлены для полноты картины,но не создаются и не используются.
 start: TStartUpInfo;
 ProcessInfo: TProcessInformation;
 Buffer: Pchar;
 BytesRead: DWord;
 Apprunning: DWord;
 avail : dword;
 notread:dword;
 stop:boolean;
 Begin
 stop := false;
 With Security Do Begin // инициализация структуры
 nlength := SizeOf(TSecurityAttributes);
 binherithandle := true;
 lpsecuritydescriptor := Nil;
 End;
 Createpipe(InReadPipe, InWritePipe, @Security, 0);
 Createpipe(ErrReadPipe, ErrWritePipe, @Security, 0);
 If Createpipe(OutReadPipe, OutWritePipe, @Security, 0) Then Begin
 // создали трубу для выхлопа бэкграунд-приложения
 Buffer := AllocMem(ReadBuffer + 1);
 // создали буфер для чтения
 FillChar(Start, Sizeof(Start), #0);
 // заполнили содержимое стартовой структуры #0
 start.cb := SizeOf(start);
 start.hStdOutput := OutWritePipe;
 start.hStdError := OutWritePipe;
 start.hStdInput := InReadPipe;
 (*************************************************************
 такой себе опширненьний комментарий...
 Оказывается, мать их так, если сделать перенаправление
 вывода в трубы, но не читать его, то если он(вывод)
 будет достаточно длинный и сможет переполнить буфер,
 который изначально отводится под трубу, то пишущий поток
 остановится и будет ждать пока не освободится место в
 буфере трубы. Как только оно освободилось, он сможет
 продолжать работу и писать дальше.
 
 start.hStdOutput := OutWritePipe;
 start.hStdError := OutWritePipe;
 
 почему собственно такой странный код: два потока
 перенаправлены в одну трубу?
 Потому что некоторые замечательные проги типа 7zip свой
 вывод направляют не в StdOut, а почему то в StdErr...
 и если для этих двух потоков назначить две разных трубы,
 а читать только одну, то произойдет то, что описано выше.
 РРРРРРРРРРРРРРРРРРРРРРРРР!!!!!!!!! сопли, слюни, ярость и
 буйное помешательство на почве программирования под винду.
 
 Может стоит сделать две трубы и читать каждую в отдельное
 мемо???
 **************************************************************)
 start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
 start.wShowWindow := SW_HIDE;
 // окно прячем
 
 If CreateProcess(Nil, PChar(CmdLine), @Security, @Security, true, NORMAL_PRIORITY_CLASS,
 Nil, Nil, start, ProcessInfo) Then Begin
 // создали процесс
 Repeat
 Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 100);
 PeekNamedPipe(OutReadPipe, @Buffer[0], ReadBuffer, @BytesRead, @avail, @notread);
 // PeekNamedPipe копирует из буфера трубы и оставляет его в первоначальном состоянии
 // в то время как ReadFile читая из трубы - опустошает ее.
 // PeekNamedPipe можно использовать для того чтобы узнать сколько данных есть в трубе
 // и если в PeekNamedPipe передать 2 и 3 параметры пустыми, то она просто скажет
 // сколько данных есть в трубе
 if avail > 0 then begin
 ReadFile(OutReadPipe, Buffer[0], BytesRead, BytesRead, Nil); // *******
 // ReadFile при чтении из трубы опустошает ее(трубы) буфер.
 end
 else begin
 if Apprunning <> 258 then
 stop := true;
 end;
 // читаем через читающий конец трубы из вывода консоли
 Buffer[BytesRead] := #0;
 // последний символ #0 - конец буфера
 OemToAnsi(Buffer, Buffer);
 // перевели из кодировки DOS в кодировку WIN
 AMemo.Text := AMemo.text + String(Buffer);
 // то что прочитали приписали к тексту в мемо
 Application.ProcessMessages;
 // обработали очередь сообщений
 // Until ((Apprunning <> WAIT_TIMEOUT) or (avail < 0));
 Until stop;
 // прервемся когда процесс завершится
 End;
 FreeMem(Buffer); // освободили буфер
 CloseHandle(ProcessInfo.hProcess); // закрыли все хендлы
 CloseHandle(ProcessInfo.hThread);
 CloseHandle(OutReadPipe);
 CloseHandle(OutWritePipe);
 CloseHandle(InReadPipe);
 CloseHandle(InWritePipe);
 CloseHandle(ErrReadPipe);
 CloseHandle(ErrWritePipe);
 End;
 // конец.
 End;
Инкапсуляция консоли
- Код: Выделить всё
 Const Con_h:hwnd =0;
 SearchHandle:hwnd =0;
 function EnumProc(h:HWND; lParam:DWord):boolean; stdcall;
 var
 ProcessId, z:cardinal;
 begin
 Result:=True;
 GetWindowThreadProcessId(h, ProcessId);
 If ProcessId=lParam then
 begin
 SearchHandle:=h;
 Result:=False;
 end;
 end;
 procedure TForm1.Run_IN_RealConsle;
 var
 ExecInfo: TShellExecuteInfoA;
 buf:array[1..100] of char;
 S:String;
 P:Pointer;
 Var
 StartTime:QWord;
 begin
 ..
 ZeroMemory(@si, sizeof(si));
 si.cb:=SizeOf(si);
 P:=@EnumProc;
 CreateProcess(nil, 'cmd /C TmpListCmd.Bat', nil, nil, false, 0, nil, nil, @si,@pi);
 SearchHandle:=0;
 sleep(150);
 StartTime:=GetTickCount64;
 While (SearchHandle=0) and ( GetTickCount64-StartTime<2000) do
 begin
 Windows.EnumWindows(@EnumProc,Lparam( pi.dwProcessId) );
 Application.ProcessMessages;
 end;
 if SearchHandle<>0 then begin
 Con_H:=SearchHandle;
 ...
 windows.SetWindowLong(Con_H, GWL_STYLE, WS_VISIBLE + WS_POPUP);
 windows.SetParent(Con_h,panel11.Handle);
 windows.MoveWindow(Con_h,0,0,panel11.Width,panel11.Height,true);
 end;
 end;
То есть мне нужен некий гибрид обоих методов работы с консолью (захватить без скрытия и дублировать вывод обратно в консоль которую в свою очередь можно инкапсулировать ) или дополнительная надстройка над "инкапсуляцией" ( с периодическим чтением тестового буфера консоли ).
Добавлено спустя 36 минут 39 секунд:
Зы
Что-то такое нашел но как-то это пока что криво у меня выходит. ( + Еще бы событие на обновление найти бо отслеживать по таймеру не очень надежно )
https://delphisources.ru/forum/showthread.php?t=7520
Добавлено спустя 12 минут 28 секунд:
Бр голова распухает ...
https://question-it.com/questions/67219 ... stochnikov





 )
  )