Могу ли я установить LowLevelMouseProc и LowLevelKeyboardProc в основной EXE - PullRequest
3 голосов
/ 28 октября 2009

Глобальные хуки Windows должны быть в DLL, потому что хук будет вызываться в контексте другого процесса, поэтому код процедуры хука должен быть введен в этот процесс. Однако есть ограничения :

SetWindowsHookEx можно использовать для инъекции DLL в другой процесс. 32-битный DLL не может быть введена в 64-битную процесс, а 64-битная DLL не может быть впрыскивается в 32-битный процесс. Если приложение требует использования крючков в других процессах требуется что вызов 32-битного приложения SetWindowsHookEx для введения 32-битного DLL в 32-битные процессы, и 64-битный вызов приложения SetWindowsHookEx для внедрения 64-битного DLL в 64-битных процессах. 32-разрядный и 64-битные библиотеки DLL должны иметь разные имена.

По этой причине я бы предпочел использовать низкоуровневые хуки WH_MOUSE_LL и WH_KEYBOARD_LL вместо WH_MOUSE и WH_KEYBOARD. Как видно из их документации :

Этот хук вызывается в контексте поток, который установил это. Вызов сделано путем отправки сообщения нить, на которой установлен крючок. Таким образом, поток, который установлен хук должен иметь цикл сообщений.

Это наводит меня на мысль, что эти конкретные процедуры подключения не обязательно должны находиться в отдельной DLL, а могут просто находиться внутри EXE-файла, который их подключил. Документация для SetWindowsHookEx, однако, гласит:

lpfn

[in] Указатель на процедуру подключения. Если параметр dwThreadId равен нулю или указывает идентификатор нить, созданная другим процесс, параметр lpfn должен указывать подключить процедуру в DLL.

Не упоминается явное исключение для двух низкоуровневых хуков.

Я видел несколько приложений .NET, которые используют низкоуровневые хуки без процедур хуков в отдельной DLL. Это еще один намек на то, что это приемлемо. Тем не менее, я немного боюсь сделать это сам, так как документация запрещает это.

Кто-нибудь предвидит какие-либо проблемы, если я не использую DLL и просто вставляю эти низкоуровневые процедуры подключения прямо в мой EXE-файл?

Редактировать : Для награды я хотел бы получить окончательное "да, это нормально, потому что ..." или "нет, это может пойти не так, потому что ..."

Ответы [ 5 ]

3 голосов
/ 02 ноября 2009

Существует одно исключение для глобальной функции перехвата в правиле dll. Низкоуровневые перехваты мыши и клавиатуры выполняются в контексте вызывающего процесса, а не перехватываемого процесса (внутренне Windows уведомляет ваш перехват через сообщение Windows). Поэтому код хука не выполняется в произвольном процессе и может быть записан в .Net. См. http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx для примера.

Для других перехватчиков вам необходимо вызвать 32-битную версию SetWindowsHookEx, передать функцию перехвата в 32-битном процессе, вызвать 64-битную версию SetWindowsHookEx и передать функцию перехвата в 64-битном процессе.

2 голосов
/ 10 марта 2010

Оказывается, это на самом деле в документации. Хотя не в документации SetWindowsHookEx и друзей, а в статье базы знаний .NET .

Процедуры низкоуровневой зацепки вызываются на нити, в которой установлена ​​зацепка. Низкоуровневые хуки не требуют реализации процедуры хуков в DLL.

1 голос
/ 28 октября 2009

Глобальные хуки, как низкого, так и высокого уровня, должны быть в отдельной DLL, которую можно загрузить в каждый процесс. В документации, которую вы процитировали, об этом достаточно ясно сказано, и если бы существовало исключение, применяемое к хукам низкого уровня, эта документация также говорила бы.

0 голосов
/ 03 ноября 2009

Редактировать: я забираю свой предыдущий ответ. Оказывается, что WH_MOUSE_LL и WH_KEYBOARD_LL являются исключениями из обычного правила о глобальных хуках:

Для чего используется HINSTANCE, переданный в SetWindowsHookEx?

0 голосов
/ 02 ноября 2009

Практическое правило. Когда в документах говорится, что ничего не нужно делать, обычно для этого есть довольно веская причина. Хотя он может работать в некоторых случаях, тот факт, что он работает, может быть деталью реализации и может быть изменен. Если это произойдет, ваш код будет нарушен, если реализация когда-либо будет изменена.

...