Могу ли я поместить LowLevelMouseProc и LowLevelKeyboardProc в основной EXE-файл?
Вопрос
Глобальные хуки 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-файл?
Изменить . Для награды я бы хотел получить окончательный ответ "да, это нормально, потому что ... " или "нет, это может пойти не так, потому что ...".
Решение
Существует одно исключение для глобальной функции перехвата в правиле dll. Низкоуровневые перехваты мыши и клавиатуры выполняются в контексте вызывающего процесса, а не перехватываемого процесса (внутренне Windows уведомляет ваш перехват через сообщение Windows). Поэтому код хука не выполняется в произвольном процессе и может быть записан в .Net. См. http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx для примера.
Для других хуков вам нужно вызвать 32-битную версию SetWindowsHookEx, передать функцию хука в 32-битном процессе, вызвать 64-битную версию SetWindowsHookEx и передать функцию хука в 64-битном процессе.
Другие советы
Оказывается, это есть на самом деле в документации. Хотя не в документации SetWindowsHookEx
и друзей, а в базе знаний .NET статья .
Низкоуровневые подключаемые процедуры вызываются в потоке, в котором установлен подключаемый модуль. Низкоуровневые хуки не требуют, чтобы процедура хуков была реализована в DLL.
Глобальные хуки, как низкого, так и высокого уровня, должны находиться в отдельной DLL, которую можно загрузить в каждый процесс. В документации, которую вы процитировали, об этом достаточно ясно сказано, и если бы существовало исключение, применяемое к низкоуровневым хукам, эта документация также говорила бы об этом.
Практическое правило. Когда в документах говорится, что ничего не нужно делать, обычно для этого есть довольно веская причина. Хотя он может работать в некоторых случаях, тот факт, что он работает, может быть деталью реализации и может быть изменен. Если это произойдет, ваш код будет нарушен, если реализация когда-либо будет изменена.
Редактировать: я забираю свой предыдущий ответ. Оказывается, что WH_MOUSE_LL и WH_KEYBOARD_LL являются исключениями из обычного правила о глобальных хуках:
Для чего используется HINSTANCE, передаваемый в SetWindowsHookEx? а> р>