SetWindowsHookEx зависает при быстром вводе или удержании кнопки клавиатуры

У меня проблема с регистратором клавиатуры. Все системы, протестированные до сегодняшнего дня, работают нормально, за исключением Windows 7 Embedded Standard 32 bit, которая, по-видимому, сходит с ума с текущей сборкой.

Что мне нужно сделать, так это записать нажатия клавиш, введенные с клавиатуры, пока я не получу их определенное количество. Когда я это делаю, я вызываю определенную процедуру.

У меня есть крючок, определенный следующим образом:

SetWindowsHookEx(WH_KEYBOARD_LL, keyboardProcedure, GetModuleHandle(NULL), 0);

и обратный вызов процедуры клавиатуры:

LRESULT CALLBACK SystemKeyboardReadWrite::keyboardProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
   ... 
}

Я использую Qt 5.2 для этого приложения.

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

Эта проблема возникает только в этой ОС, ни в одной другой ОС Windows 7 или Windows XP я не замечал этой проблемы. У меня есть 2 компьютера с одинаковой настройкой, и они оба показывают одну и ту же проблему, также я разрабатываю приложение на профессиональной Windows 7, и это тоже выглядит нормально. Мне интересно, является ли это проблемой с моим приложением, или это что-то вне моего контроля.

Спасибо всем за помощь.


person Trevor Donahue    schedule 22.08.2014    source источник
comment
Судя по данной сигнатуре, ваша ловушка-процедура является функцией члена в классе. Это никогда не должно было сработать. Это должна быть статическая функция, если она определена в классе. Я предполагаю, что вы просто забыли скопировать и вставить модификатор static? Помимо этого, обычная причина этой проблемы заключается в том, что внутри процедуры ловушки выполняется слишком много работы. Вы не показываете нам код, который там содержится, так что мы можем только догадываться. Хотя, конечно, это должно было вызвать проблемы в других системах. Я ни в коем случае не эксперт по встраиваемым Windows. Трудно представить, чем отличается.   -  person Cody Gray    schedule 22.08.2014
comment
Я вставил код из файла .cpp. Но да, это статический метод, вот определение из шапки. static LRESULT CALLBACK keyboardProcedure(int nCode, WPARAM wParam, LPARAM lParam);. Я вставил только голые кости, необходимые для решения проблемы, я вычислил небольшую сборку с относительно небольшим содержимым обратного вызова, и проблема все еще сохраняется, поэтому детали внутри обратного вызова не имеют значения. Но спасибо за внимание   -  person Trevor Donahue    schedule 22.08.2014


Ответы (1)


Я не знаю Windows Embedded, но я знаком с Windows 7 и хуками LowLevel, как с мышью, так и с клавиатурой.

Симптом исключения из списка ловушек можно уменьшить/изменить с помощью значения реестра LowLevelHooksTimeOut. Вы должны перезагрузить систему после ее изменения. По сути, это значение указывает количество миллисекунд, в течение которых хуки должны взаимодействовать с ключами.

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

Например, вы получаете 100 нажатий клавиш, затем записываете их в файл. Если они держат нажатыми клавиши от 100 до 101+, а вы тратите больше времени на хук, чем максимальное, Windows внесет ваш обратный вызов в черный список и вычеркнет вас из списка хуков.

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

У меня также есть только действительно используемые хуки, которые установлены в dll и удерживают глобальный дескриптор HHOOK. Просмотр всех кодов возврата ваших функций также может пролить свет на ситуацию.

Дополнительная информация о LowLevelHooksTimeout:

Низкоуровневый хук клавиатуры работает на одном на Windows 7 x64 и не работает на другом

person phyatt    schedule 22.08.2014
comment
Спасибо, очень полезно! Я попробую изменить значение реестра и посмотреть, работает ли это. Я дам вам знать через несколько часов. Спасибо еще раз :) - person Trevor Donahue; 22.08.2014
comment
Также в качестве потенциального решения я бы попробовал запустить клавиатурный хук из другого потока, может ли это иметь значение? Я заметил это как потенциальное решение здесь: callback-proc-stops-get-call-after-exceeding-max-time-allowed?forum=windowsgeneraldevelopmentissues#d378145f-ab4c-4108-9df3-22a7d3bb7e8f" rel="nofollow noreferrer">social.msdn.microsoft.com/Forums /windowsdesktop/en-US/ Спасибо за ваш вклад :) - person Trevor Donahue; 22.08.2014
comment
Да. Помимо запуска в DLL, я всегда запускал и запускал свои хуки в отдельном потоке с высоким приоритетом. - person phyatt; 22.08.2014
comment
Ох, ну ладно. Можете ли вы найти мне пример, иллюстрирующий это? - person Trevor Donahue; 22.08.2014
comment
Qt может очень хорошо выполнять многопоточность. Почитайте QThread, и вы сможете это сделать. - person phyatt; 22.08.2014