Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.18;
Скачать: CL | DM;

Вниз

Как получить массив символов dos-окна?   Найти похожие ветки 

 
Guest32545654   (2004-03-28 16:50) [0]

Здравствуйте. В режиме чистого DOS"а есть возможность получить доступ к памяти, из которой отражаются данные (символы) на экран.

Ситуация: Запускаю DOS-программу из-под Windows (98,2000). Через заданный интервал времени, нужно получить полный массив символов, который в данный момент отражается в DOS-окне.

Желательно описать способ перехвата символов окна, развернутого как на полный экран, так и не на полный.


 
Piter ©   (2004-03-28 20:10) [1]

Блин, ну ты и сформулировал вопрос... если я тебя правильно понял, то вот откуда-то с sources.ru:

Запуск программ с передачей консольного ввода и чтением вывода.
Компилятор: Delphi

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

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

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;


 
PVOzerski ©   (2004-03-28 23:26) [2]

А вот не могу сейчас дать ответ на вопрос :^( Однако предупреждаю: то, что изложено в [1], может и не сработать. Дело в том, что DOS-программы выводят текст на экран разными способами. Если через стандартные i/o ф-ции DOS- всё OK. А если через int 10H (если не путаю номер "видеопрерывания": давно это было) или вообще через видеопамять? Я бы лучше написал под DOS скрингрэббер, это вернее (и не так уж сложно, особенно, если не делать резидента, а вызывать из своей проги нужную через exec. Да и TSR здесь не так уж сложен). Хотя IMHO, не более того.


 
Германн ©   (2004-03-29 02:14) [3]

И Вы правы - PVOzerski ©   (28.03.04 23:26) [2]
В DOS-программах, никогда не использовал не то что DOS-прерываний, но и BIOS-прерываний. Всегда пользовался функциями ТР, пишущими прямо в ВидеоПамять.

И, кстати, TSR-программу, которая записывает экран, тут написать несложно.


 
nikkie ©   (2004-03-29 02:31) [4]

ReadConsoleOutputCharacter?


 
Думкин ©   (2004-03-29 07:16) [5]

> PVOzerski ©   (28.03.04 23:26) [2]

Выводили по разному, но хранились одинаково в текстовом режиме. слово на символ. адрес - $0B00:0000 кажется.


 
PVOzerski ©   (2004-03-29 10:10) [6]

$B800:0000 (но не у Hercules, там адрес другой, какой - не помню ...


 
Думкин ©   (2004-03-29 10:22) [7]

> PVOzerski ©   (29.03.04 10:10) [6]

Точно. Нолик глупо впереди. :-)
А графрежим у VGA - $A000:0000. А вот с SuperVGA - возиться приходилось.



Страницы: 1 вся ветка

Текущий архив: 2004.04.18;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.054 c
7-1076391878
Alexandr3
2004-02-10 08:44
2004.04.18
Считыватели магнитных карт


14-1080299177
Романов Р.В.
2004-03-26 14:06
2004.04.18
Опрос - поиск файлов


8-1073287268
serg128
2004-01-05 10:21
2004.04.18
как записать звук с микрофона? (по возможности на API)?


11-1063004039
JT
2003-09-08 10:53
2004.04.18
StatusBar


1-1080889595
still_swamp
2004-04-02 11:06
2004.04.18
D8 Assembler