Текущий архив: 2004.06.13;
Скачать: CL | DM;
ВнизПомогите разобраться с доступом к содержимому окна вывода консоли Найти похожие ветки
← →
vertal (2004-04-25 01:02) [0]Я устанавливаю горячую клавишу , при обработке события от ее нажатия хочу проверить , является ли активное окно(не моей программы) консольным , и если да , то получить его экран вывода(символы и атрибуты).Пишу:
...
Var
IsFocusOnConsole:Bool;
ConsoleScreenBufferInfo:_Console_Screen_Buffer_Info;
begin
IsFocusOnConsole:=GetConsoleScreenBufferInfo
(GetForegroundWindow,ConsoleScreenBufferInfo);
...
End;
Проблема в том , что IsFocusOnConsole=0 всегда , даже если активно консольное окно , а GetLastError возвращает 6(INVALID_HANDLE_VALUE).Подскажите , что здесь не так?
← →
Polevi © (2004-04-25 09:47) [1]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getconsolescreenbufferinfo.asp
что первым параметром надо передавать ?
← →
vertal (2004-04-26 17:08) [2]to Polevi
Первым параметром передается хэндл данного буфера.Я подозревал , что это и хэндл консольного окна,получаемый через GetForegroundWindow - не одно и то же , но не понял , как получить первое , зная второе?
← →
Polevi © (2004-04-26 18:09) [3]никак
← →
vertal (2004-04-28 23:15) [4]to Polevi
Извиняюсь за опоздание , были проблемы с доступом к интернету.
Не понял , что значит никак? Я что-то не понимаю (дело не в том , что GetForegroundWindow возвращает не нужный мне дескриптор буфера , а в правах доступа к этим дескрипторам ? ) или вы действительно не знаете , как решить поставленную задачу?Объясните мне пожалуйста , что вы имеете в виду под "никак" , пусть даже скажите , что я полный чайник в API , но все - таки я бы хотел закрыть этот вопрос - на худой конец отправьте к какому-нибудь разделу справки , но конкретному , потому что MS SDK Help в комплекте Delphi я уже просмотрел и не нашел там ответа .
← →
BiN © (2004-04-28 23:23) [5]>>vertal (25.04.04 01:02)
Если объяснишь главную цель, возможно, поможем.
← →
vertal (2004-04-30 00:28) [6]Цель - получить экран вывода активной консольной программы в описанных условиях и далее провести некоторые операции с этим экраном. Провести операции - не проблема , проблема , как я уже сказал , заключается в том , что GetConsoleScreenBufferInfo и ReadConsoleOutput не отрабатывают , как я хочу.Если вам очень интересно , то могу сказать , что я задумал программу , которая по этой горячей клавише (Ctrl+PrintScreen в идеале ) будет запихивать в буфер html-код этого экрана с сохранением цветов , таким образом можно будет получать компактные "скриншоты" консольных прог.
← →
Cobalt © (2004-04-30 00:41) [7]Даю наводку - как получить хендл консольного буфера (или что там у него)?
Это вы знаете? Или, быть может, сможете найти?
Я, например, не в курсе. Но, если бы передо мной стояла бы эта проблема, то это был бы мой первый ход.
← →
Polevi © (2004-04-30 08:13) [8]можно внедриться в консольный процесс
← →
BiN © (2004-04-30 09:22) [9]можно внедриться в консольный процесс
imho это единственный 100%-й способ (конечно для NT и иже с ним)
← →
BiN © (2004-04-30 09:49) [10]хотя нет в XP еще есть AttachConsole
← →
Polevi © (2004-04-30 13:48) [11]внедриться в чужой процесс можно и в 9x
← →
BiN © (2004-04-30 23:13) [12]Polevi © (30.04.04 13:48) [11]
Можно и драйвер для этого написать, а смысл?
править образ kernel32 в общедоступной памяти - оправдывает ли цель средства. imho трудно будет избежать сбоев системы.
← →
vertal (2004-05-01 01:28) [13]Ну не нашел я , как получить этот хендл . А внедриться в чужой процесс - это как ?
← →
Марсианин © (2004-05-02 03:00) [14]почитал хелп -- нихрена не понял.. если надо внедряться -- внедримся, а если я хочу получить его в своем приложении?
впрочем пример из МСДН вносит некотурую ясность
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-03 00:29) [15]В этом примере как я понимаю происходит получение стандартной консоли , ассоциированной с вызывающим эти функции (GetStdHandle) приложением. Мне же не нужно создавать никаких консолей , а к описанной задаче этот пример мало подходит.
← →
Polevi © (2004-05-03 09:13) [16]> [15] vertal (03.05.04 00:29)
твоя задача заключается в том, чтоюы выполнить похожий код в чужом процессе
по нажатию горяечей клавиши ты должен внедрить свой код в адресное пространство конмольного процесса и передеать ему управление. этот код получит хендл буфера с помощью GetStdHandle, и любым IPC механизмом передаст его содержимое буфера твоей программе
← →
vertal © (2004-05-04 00:33) [17]>по нажатию горяечей клавиши ты должен внедрить свой код в
>адресное пространство конмольного процесса и передеать ему
>управление.
Хорошо , как в таком случае можно внедриться в адресное пространство другого приложения?
← →
VMcL © (2004-05-04 03:25) [18]>>vertal © (04.05.04 00:33) [17]
>Хорошо , как в таком случае можно внедриться в адресное пространство другого приложения?
Способов несколько. См. в книге Рихтера:
http://www.podgoretsky.com/ftp/Docs/Classics/Richter/
← →
vertal © (2004-05-06 01:20) [19]Код , подобный [14] , действительно работает , спасибо за разъяснения . Однако пока не получается выполнить его по горячей клавишше и для любого окна (отработало это только в виде плагина к фару , при явном вызове функции из dll фаром).А когда обрабатываю свою глобальную ловушку , установленную из этой же dll , результат все время такой , как описано в [1] , хотя теперь dll по идее должна работать в адресном пространстве приложения , которому направлялось событие от нажатия клавиш (и она в него загружается , GetWindowText(GetActiveWindow,...) дает заголовок любого активного окна)
← →
Polevi © (2004-05-06 08:04) [20]>хотя теперь dll по идее должна работать в адресном пространстве приложения
проверь это, идентифицируй процесс, выведи окошко с paramstr(0) чтоли :)
← →
vertal © (2004-05-07 00:52) [21]> проверь это, идентифицируй процесс, выведи окошко с 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)
Кто-нить знает , что здесь не так?
← →
vertal © (2004-05-07 01:52) [22]Сорри за предыдущее сообщение - я несколько повторился
Теперь проверил и по ParamStr(0)... ParamStr(0) возвращает имя exe только если активно GUI приложение ; если активна консоль (и DOS - и Windows - программ , неважно ) , то ParamStr(0)=[SYSDIR]\kernel32.dll . Что это значит ?
Я теперь думаю , глобальный хук нельзя применять для внедрения в адресное пространство консольных приложений (о чем в принципе сказано и у Рихтера , и в MS SDK Help ), да и сам хук на клавиатуру в принципе не работает в консоле (специфицированная функция вызывается только при нажатии PrintScreen в консоли , при нажатии любых других клавиш она не вызывается ).
Видел у Рихтера вариант внедрения с CreateRemoteThread , но хочу , чтобы работало во всех виндах.
Можете что-нибудь посоветовать?
← →
BiN © (2004-05-07 13:39) [23]Видел у Рихтера вариант внедрения с 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
← →
марсианин © (2004-05-07 23:44) [24]здравый смысл подсказывает, что мы слегка перегибаем палку.. для того, чтоб получить доступ к чужой консоле внедряем ДЛЛ, перехватываем вызовы ВинАПИ и тп..
наверняка майкрософт придумал чего по-проще.. напр. AttachConsole вполне подошла бы, но она только на семействе WinNT.. может быть, для 98 кроме внедрения/перехвата выхода нет.. но стоит еще порыться
← →
vertal © (2004-05-08 00:13) [25]to Bin[23]
Спасибо за ссылки , обязательно посмотрю .
Я тут правда уже раскопал на http://www.madshi.net модуль , который имеет функцию InjectLibrary/UnInjectLibrary , которая работает во всех виндах . Теперь по горячей клавише вызываю эту функцию , внедряю свою библиотеку с собственно алгоритмом преобразования и все работает , только при условии , что активная консоль - это Windows - программа (far) или DOS - программа , но которая запускалась в той же консоли фаром .Если же активная консоль - DOS - программа , запущенная не из-под фара , то задачу опять не удается решить.
Страницы: 1 вся ветка
Текущий архив: 2004.06.13;
Скачать: CL | DM;
Память: 0.52 MB
Время: 0.036 c