Я думаю, что у вас проблемы, потому что вы пытаетесь реализовать функцию ловушки в C #. Основываясь на документации pinvoke.net на SetWindowsHookEx()
, он говорит, что вы не можете сделать это - процедура подключения должна быть в неуправляемой DLL. В противном случае это приведет к загрузке вашей DLL во все запущенные процессы с помощью цикла сообщений, что, в свою очередь, приведет к загрузке и запуску CLR в каждом процессе. Это не только займет много времени, но внедрение CLR во все процессы, вероятно, не лучшая идея. Кроме того, что произойдет, если у процесса уже есть работающий CLR, отличный от того, на котором была построена ваша DLL?
Наилучшим подходом было бы переместить этот код в неуправляемую DLL-библиотеку C ++ и использовать какое-то межпроцессное взаимодействие для отправки данных, перехваченных процедурой ловушки, обратно в ваше приложение.
Обновление
Во-первых (и это, вероятно, не вызывает вашей проблемы), почему вы звоните LoadLibrary()
, чтобы получить HINSTANCE
вашей DLL? Вероятно, было бы лучше вызвать GetModuleHandle () , поскольку ваша DLL уже загружена.
А почему ваша процедура ловушки никогда не вызывается - как вы это проверили? Поскольку вы перехватываете все потоки GUI в системе, это означает, что ваша DLL должна быть загружена во все процессы GUI. Вполне вероятно, что вы не увидите результатов вызова wprintf()
, потому что другие процессы не имеют консольного окна для отображения вывода.
Чтобы убедиться, что ваша DLL загружена правильно, используйте программу, в которой перечислены библиотеки DLL, загруженные процессом (мне нравится Process Explorer ). Вы можете использовать Find | Найдите элемент меню Handle или DLL для поиска имени вашей DLL - оно должно отображаться во всех процессах с циклом сообщений.
После того, как вы проверили, что ваша DLL загружена, чтобы увидеть, вызвана ли ваша ловушка, вы можете присоединить отладчик к другому процессу (например, «Блокнот»), а затем установить точку останова в своей функции ловушки. Это должно происходить всякий раз, когда сообщение отправляется на крючок CBT. Если вы не хотите использовать отладчик, вы можете изменить вызовы на wprintf()
на OutputDebugString () и запустить утилиту, подобную DebugView , для мониторинга результатов.
Наконец, поскольку ваша подключаемая функция вызывается в контексте другого процесса, ваша переменная m_HookHandle
там не будет действительной. Вы должны хранить его в сегменте общих данных , чтобы все загруженные экземпляры вашей DLL имели одинаковое значение.