【问题标题】:explorer.exe crashes when global touch hook via WH_GETMESSAGE is enabled启用通过 WH_GETMESSAGE 的全局触摸挂钩时 explorer.exe 崩溃
【发布时间】:2019-07-11 10:35:10
【问题描述】:

我正在开发一个在全球范围内侦听触摸事件的应用程序,为此我设置了一个挂钩来检索 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 here 上设置全局挂钩的信息。

  • 我还在我的应用窗口中调用了RegisterTouchWindow 函数来启用接收触摸事件。

【问题讨论】:

  • 您必须为全局挂钩使用 DLL(低级挂钩除外)
  • 我设法为全局钩子创建了一个 DLL,它有点工作。我遇到了另一个问题,其中只有一个应用程序被钩住,而不是所有应用程序。我将在这里回答主要问题,并为下一个问题创建一个新的问题线程。
  • 创建了一个新问题,详细说明上述问题here

标签: c# winforms hook loadlibrary setwindowshookex


【解决方案1】:

我会尽可能详细地回答我的问题,以便其他初学者了解发生了什么。

首先,我遵循了如何从MSDN Hook Documentation 创建钩子的指南,但该示例显示了它在 c++ 上的用法。在使用SetWindowHookEx 搜索参考资料后,我读到的示例涉及挂钩低级 Windows 挂钩。这些钩子,即WH_KEYBOARD_LLWH_MOUSE_LL,是最常见的教程,可以全局钩子,而无需将它们的钩子进程分离成一个dll。 WH System Events 的其余部分如果要全局挂钩,则需要分离。这也在文档中进行了描述:

您必须将全局挂钩过程放置在与安装挂钩过程的应用程序分开的 DLL 中。安装应用程序必须具有 DLL 模块的句柄才能安装挂钩过程。

背后的粗略想法是将钩子函数注入到所有正在运行的线程中。对于使用User32.dll 作为挂钩库的WH_KEYBOARD_LLWH_MOUSE_LL,这很好。但是,如果您像我一样将它用于其他系统事件,则该过程可能会使您的整个桌面崩溃,就像它发生在我身上一样。

我的应用程序是用 C# 编码的,所以我必须用 c++ 创建一个 dll,然后将它链接到我的 C# 应用程序。另外,阅读pInvokes 以便能够使用LoadLibraryGetProcAddress

您可以从 Visual Studio 本身创建 dll 文件。您只需修改 dllmain.cpp 文件。我从这个example玩了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);
 }

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多