Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите разобраться с доступом к содержимому окна вывода консоли


Страницы:   1 2

vertal ©   (2004-04-25 01:02:00) 

Я устанавливаю горячую клавишу , при обработке события от ее нажатия хочу проверить , является ли активное окно(не моей программы) консольным , и если да , то получить его экран вывода(символы и атрибуты).Пишу:


...
Var
IsFocusOnConsole:Bool;
ConsoleScreenBufferInfo:_Console_Screen_Buffer_Info;
begin
  IsFocusOnConsole:=GetConsoleScreenBufferInfo
    (GetForegroundWindow,ConsoleScreenBufferInfo);
  ...
End;

Проблема в том , что IsFocusOnConsole=0 всегда , даже если активно консольное окно , а GetLastError  возвращает 6(INVALID_HANDLE_VALUE).Подскажите , что здесь не так?


vertal   (2004-05-08 00:13:00) [1]

to Bin[23]
Спасибо за ссылки , обязательно посмотрю .
Я тут правда уже раскопал на http://www.madshi.netмодуль , который имеет функцию InjectLibrary/UnInjectLibrary , которая работает во всех виндах . Теперь по горячей клавише вызываю эту функцию , внедряю свою библиотеку с собственно алгоритмом преобразования и все работает , только при условии , что активная консоль - это Windows - программа (far) или DOS - программа , но которая запускалась в той же консоли фаром .Если же активная консоль - DOS - программа , запущенная не из-под фара , то задачу опять не удается решить.


марсианин   (2004-05-07 23:44:00) [2]

здравый смысл подсказывает, что мы слегка перегибаем палку.. для того, чтоб получить доступ к чужой консоле внедряем ДЛЛ, перехватываем вызовы ВинАПИ и тп..

наверняка майкрософт придумал чего по-проще.. напр. AttachConsole вполне подошла бы, но она только на семействе WinNT.. может быть, для 98 кроме внедрения/перехвата выхода нет.. но стоит еще порыться


BiN   (2004-05-07 13:39:00) [3]

Видел у Рихтера вариант внедрения с CreateRemoteThread , но хочу , чтобы работало во всех виндах.
Можете что-нибудь посоветовать?


http://delphimaster.ru/articles/Dapi/index.html
http://internals.com/articles/apispy/apispy.htm
http://maxcomputing.narod.ru/ahijack2.html
http://maxcomputing.narod.ru/ahijack3.html


vertal   (2004-05-07 01:52:00) [4]

Сорри за предыдущее сообщение - я несколько повторился

Теперь проверил и по ParamStr(0)... ParamStr(0) возвращает имя exe только если активно GUI приложение ; если активна консоль (и DOS - и Windows - программ , неважно ) , то ParamStr(0)=[SYSDIR]\kernel32.dll . Что это значит ?
Я теперь думаю , глобальный хук нельзя применять для внедрения в адресное пространство консольных приложений (о чем в принципе сказано и у Рихтера , и в MS SDK Help ), да и сам хук на клавиатуру в принципе не работает в консоле (специфицированная функция вызывается только при нажатии PrintScreen в консоли , при нажатии любых других клавиш она не вызывается ).
Видел у Рихтера вариант внедрения с CreateRemoteThread , но хочу , чтобы работало во всех виндах.
Можете что-нибудь посоветовать?


vertal   (2004-05-07 00:52:00) [5]

> проверь это, идентифицируй процесс, выведи окошко с paramstr(0) чтоли :)

Ситуация следующая:
GetStdHandle(STD_OUTPUT_HANDLE),совершенно необходимая функция для дальнейших действий , у меня отрабатывает успешно в двух случаях :
1) Из моего exe консольной программы
2) При вызове из dll - плагина к far , если явно вызывается farом через OpenPlugin

При вызове же из обработчика события , на который установлен глобальный хук из этой же dll(в соответствии с рекомендациями Рихтера) , GetStdHandle(STD_OUTPUT_HANDLE) всегда неуспешна (возвращает -1), даже если активно консольное окно .dll по-моему все-таки загружается в АП активного процесса , о чем я сужу по признакам:
а) Выполняется ее код инициализации при отображении в каждый новый процесс(то что между Begin и End.)
б) GetWindowText(GetActiveWindow,buf,buflen) пишет в буфер заголовок активного окна
GetLastError после GetStdHandle(STD_OUTPUT_HANDLE) возвращает при первом вызове из нового процесса
2 (ERROR_FILE_NOT_FOUND)
, а при всех последующих -
87 (ERROR_INVALID_PARAMETER)

Кто-нить знает , что здесь не так?


Polevi   (2004-05-06 08:04:00) [6]

>хотя теперь dll по идее должна работать в адресном пространстве приложения
проверь это, идентифицируй процесс, выведи окошко с paramstr(0) чтоли :)


vertal   (2004-05-06 01:20:00) [7]

Код , подобный  [14] , действительно работает , спасибо за разъяснения . Однако пока не получается выполнить его по горячей клавишше и для любого окна (отработало это только в виде плагина к фару , при явном вызове функции из dll фаром).А когда обрабатываю свою глобальную ловушку , установленную из этой же dll , результат все время такой , как описано в [1] , хотя теперь dll по идее должна работать в адресном пространстве приложения , которому направлялось событие от нажатия клавиш (и она в него загружается , GetWindowText(GetActiveWindow,...) дает заголовок любого активного окна)


VMcL   (2004-05-04 03:25:00) [8]

>>vertal ©  (04.05.04 00:33) [17]

>Хорошо , как в таком случае можно внедриться в адресное пространство другого приложения?

Способов несколько. См. в книге Рихтера:
http://www.podgoretsky.com/ftp/Docs/Classics/Richter/


vertal   (2004-05-04 00:33:00) [9]

>по нажатию горяечей клавиши ты должен внедрить свой код в
>адресное пространство конмольного процесса и передеать ему
>управление.
Хорошо , как в таком случае можно внедриться в адресное пространство другого приложения?


Polevi   (2004-05-03 09:13:00) [10]

> [15] vertal   (03.05.04 00:29)
твоя задача заключается в том, чтоюы выполнить похожий код в чужом процессе
по нажатию горяечей клавиши ты должен внедрить свой код в адресное пространство конмольного процесса и передеать ему управление. этот код получит хендл буфера с помощью GetStdHandle, и любым IPC механизмом передаст его содержимое буфера твоей программе


vertal   (2004-05-03 00:29:00) [11]

В этом примере как я понимаю происходит получение стандартной консоли , ассоциированной с вызывающим эти функции (GetStdHandle)  приложением. Мне же не нужно создавать никаких консолей , а к описанной задаче этот пример мало подходит.


Марсианин   (2004-05-02 03:00:00) [12]

почитал хелп -- нихрена не понял.. если надо внедряться -- внедримся, а если я хочу получить его в своем приложении?

впрочем пример из МСДН вносит некотурую ясность


HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT srctWindow;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // вот мы его, родимого, получили

// Get the current screen buffer size and window position.

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
   MyErrorExit("GetConsoleScreenBufferInfo");

// Set srctWindow to the current window size and location.

srctWindow = csbiInfo.srWindow;

// If window is not at the screen buffer top, move it up one line.

if ( srctWindow.Top > 0 )
{
   srctWindow.Top -= 1;      // move top up by one row
   srctWindow.Bottom -= 1;   // move bottom up by one row

   if (! SetConsoleWindowInfo(
              hStdout,      // screen buffer handle
              TRUE,         // absolute coordinates
              &srctWindow)) // specifies new location
       MyErrorExit("SetConsoleWindowInfo");
}
The same scrolling can be done by specifying changes in the window coordinates.

// Get the current screen buffer window position.

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
   MyErrorExit("GetConsoleScreenBufferInfo");

// If window is not at the screen buffer top, move it up one line.

if (csbiInfo.srWindow.Top > 0)
{
   srctWindow.Top = -1;      // move top up by one row
   srctWindow.Bottom = -1;   // move bottom up by one row
   srctWindow.Left = 0;      // no change
   srctWindow.Right = 0;     // no change

   if (! SetConsoleWindowInfo(
              hStdout,      // screen buffer handle
              FALSE,        // deltas, not absolute
              &srctWindow)) // specifies new location
   {
       MyErrorExit("SetConsoleWindowInfo");
   }
}


vertal   (2004-05-01 01:28:00) [13]

Ну не нашел я , как получить этот хендл . А внедриться в чужой процесс - это как ?


BiN   (2004-04-30 23:13:00) [14]

Polevi ©   (30.04.04 13:48) [11]
Можно и драйвер для этого написать, а смысл?

править образ kernel32 в общедоступной памяти - оправдывает ли цель средства. imho трудно будет избежать сбоев системы.


Polevi   (2004-04-30 13:48:00) [15]

внедриться в чужой процесс можно и в 9x


BiN   (2004-04-30 09:49:00) [16]

хотя нет в XP еще есть AttachConsole


BiN   (2004-04-30 09:22:00) [17]

можно внедриться в консольный процесс

imho это единственный 100%-й способ (конечно для NT и иже с ним)


Polevi   (2004-04-30 08:13:00) [18]

можно внедриться в консольный процесс


Cobalt   (2004-04-30 00:41:00) [19]

Даю наводку - как получить хендл консольного буфера (или что там у него)?
Это вы знаете? Или, быть может, сможете найти?
Я, например, не в курсе. Но, если бы передо мной стояла бы эта проблема, то это был бы мой первый ход.


vertal   (2004-04-30 00:28:00) [20]

Цель - получить экран вывода активной консольной программы в описанных условиях и далее провести некоторые операции с этим экраном. Провести операции - не проблема , проблема , как я уже сказал , заключается в том , что GetConsoleScreenBufferInfo и ReadConsoleOutput не отрабатывают , как я хочу.Если вам очень интересно , то могу сказать , что я задумал программу , которая по этой горячей клавише (Ctrl+PrintScreen в идеале ) будет запихивать в буфер html-код этого экрана с сохранением цветов , таким образом можно будет получать компактные "скриншоты" консольных прог.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо