Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];

Вниз

Как получить массив символов 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.033 c
1-1080718810
neodiX
2004-03-31 11:40
2004.04.18
Delphi7, XPManifest, TGroupBox - отображение кириллицы. Решение!


3-1079622632
Новичек
2004-03-18 18:10
2004.04.18
Задание степени релевантности при поиске?


4-1076643766
Aleksey
2004-02-13 06:42
2004.04.18
ctrl+c, ctrl+v


6-1076919580
Leech
2004-02-16 11:19
2004.04.18
Передача файла средствами TCP/IP


1-1080542953
Zilog
2004-03-29 10:49
2004.04.18
Как создать приложение класса TAppBuilder?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский