explorer.exe падает, когда глобальный сенсорный хук через WH_GETMESSAGE включен - PullRequest
0 голосов
/ 11 июля 2019

Я работаю над приложением, которое прослушивает сенсорные события во всем мире, для которого я настроил хук для получения WM_TOUCH сообщений. Это сообщение будет извлечено из хука WH_GETMESSAGE.

Проблема в том, что каждый раз, когда я запускаю приложение, explorer.exe просто вылетает, и его открытие займет много времени. Может ли быть кто-то знающий в этом вопросе? Я сделал это с помощью WH_KEYBOARD_LL раньше, и он не делает то же самое.

Это, и я до сих пор не получаю никаких глобальных событий касания.

Я настроил свой крючок следующим образом:

public void hook() {
            IntPtr hInstance = LoadLibrary("User32");
            hhook = SetWindowsHookEx(WH_GETMESSAGE, hookProc, hInstance, 0); // set Thread ID to 0 to listen to all threads within the same desktop
}
  • Я прочитал информацию о настройке глобальных перехватов на MSDN здесь .

  • Я также вызвал функцию RegisterTouchWindow в окне своего приложения, чтобы включить прием сенсорных событий.

1 Ответ

0 голосов
/ 16 июля 2019

Я постараюсь ответить на мой вопрос как можно более подробно, чтобы другие новички могли понять, что происходит.

Прежде всего, я следовал руководству по созданию хуков из Документация по хукам MSDN, но пример показывает его использование на c ++.Поиск ссылок на использование SetWindowHookEx примеров, о которых я читал, касался перехвата низкоуровневых хуков окон.Эти хуки, а именно WH_KEYBOARD_LL и WH_MOUSE_LL, являются наиболее распространенными уроками и могут быть глобально перехвачены без необходимости разделения их процесса хука в dll.Остальные WH System Events требуют разделения, если они должны быть подключены глобально.Это также описано в документации:

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

Грубая идея заключается в том, что функция подключения вставляется во все запущенные потоки.Для случая WH_KEYBOARD_LL и WH_MOUSE_LL, которые используют User32.dll в качестве своей библиотеки ловушек, это хорошо.Но если бы вы использовали его для других системных событий, как я, этот процесс мог привести к сбою всего вашего рабочего стола, например, как это случилось с моим.

Мое приложение было написано на C #, поэтому мне пришлось создать dllв C ++, а затем связать его с моим приложением C #.Также прочитайте о pInvokes, чтобы иметь возможность использовать LoadLibrary и GetProcAddress

. Вы можете создавать dll файлы из самой Visual Studio.Вам нужно только изменить файл dllmain.cpp.Я поигрался с WH_GETMESSAGE из этого примера

Из моего приложения C # все, что мне нужно было сделать, это вызвать функцию SetHook следующим образом:

IntPtr hInstance = IntPtr.Zero;
IntPtr hProc = IntPtr.Zero;

private delegate void HookSetting();

public void SetHook()
{
        hInstance = LoadLibrary("Dll1");

        if (IntPtr.Zero == hInstance)
        {
            //do a null check
        }
        hProc = GetProcAddress(hInstance, "_SetHook@0"); // SetHook is in its "mangled" form right here
        if(IntPtr.Zero == hProc)
        {
            //do a null check
        }

        //Ways of starting the Hook:
        // OPTION 1: calling the SetHook function of the DLL within the C# app.
        //HookSetting hookset = (HookSetting)Marshal.GetDelegateForFunctionPointer(hProc, typeof(HookSetting));
        //hookset();

        // OPTION 2: Instead of using the SetHook function, call the SetwindowsHookEx directly 
        hhook = SetWindowsHookEx(WH_GETMESSAGE, hProc, hInstance, 0);
 }
...