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

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.06.13;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.038 c
14-1085295633
R
2004-05-23 11:00
2004.06.13
Почему Пепси


1-1085720209
Марат
2004-05-28 08:56
2004.06.13
TCheckListBox


3-1084955594
GIL
2004-05-19 12:33
2004.06.13
Зараз пара запросов - не работают.


4-1084053583
Мыш
2004-05-09 01:59
2004.06.13
получение иконки не работает


14-1085383304
PEVEC
2004-05-24 11:21
2004.06.13
Karaoke





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский