Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 启用通过WH_GETMESSAGE的全局触摸挂钩时,explorer.exe崩溃_C#_Winforms_Hook_Loadlibrary_Setwindowshookex - Fatal编程技术网

C# 启用通过WH_GETMESSAGE的全局触摸挂钩时,explorer.exe崩溃

C# 启用通过WH_GETMESSAGE的全局触摸挂钩时,explorer.exe崩溃,c#,winforms,hook,loadlibrary,setwindowshookex,C#,Winforms,Hook,Loadlibrary,Setwindowshookex,我正在开发一个应用程序,它可以在全球范围内监听触摸事件,我已经设置了一个钩子来检索WM_touch消息。此消息将从WH_GETMESSAGEhook中检索 问题是每次我运行应用程序时,explorer.exe都会崩溃,需要很长时间才能再次打开。有没有人对这个问题很了解?我以前用WH\u-KEYBOARD\u-LL做过这件事,但它没有做同样的事情 这个,还有,我仍然没有得到任何全球接触事件 我已按如下方式设置了挂钩: public void hook() { IntPtr

我正在开发一个应用程序,它可以在全球范围内监听触摸事件,我已经设置了一个钩子来检索
WM_touch
消息。此消息将从
WH_GETMESSAGE
hook中检索

问题是每次我运行应用程序时,
explorer.exe
都会崩溃,需要很长时间才能再次打开。有没有人对这个问题很了解?我以前用
WH\u-KEYBOARD\u-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
    函数,以允许接收触摸事件


我将尽可能详细地回答我的问题,以便其他初学者了解正在发生的事情

<>首先,我遵循了如何创建钩子的指南,但是这个例子展示了它在C++上的用法。在使用
SetWindowHookEx
搜索了参考资料之后,我读到的示例涉及钩住低级windows钩子。这些钩子,即
WH\u-KEYBOARD\u-LL
WH\u-MOUSE\u-LL
,是最常见的教程,可以全局钩子,而无需将钩子进程分离到dll中。如果要全局挂接,其余的
WH系统事件
需要分离。这在文件中也有描述:

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

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

<>我的应用程序是用C语言编码的,所以我必须在C++中创建一个DLL,然后把它链接到我的C语言应用程序。另外,请阅读关于
pInvokes
的内容,以便能够使用
LoadLibrary
GetProcAddress

您可以从VisualStudio本身创建
dll
文件。您只需修改dllmain.cpp文件。我在这里玩了一下
WH\u 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);
 }

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