explorer.exe 在通过 WH_GETMESSAGE 启用全局触摸挂钩时崩溃
explorer.exe crashes when global touch hook via WH_GETMESSAGE is enabled
我正在开发一个在全球范围内监听触摸事件的应用程序,我已经为它设置了一个钩子来检索 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 上阅读了有关设置全局挂钩的信息。
我还调用了我的应用 window 的 RegisterTouchWindow
函数来启用接收触摸事件。
我会尽可能详细地回答我的问题,以便其他初学者了解发生了什么。
首先,我遵循了有关如何从 MSDN Hook Documentation 创建挂钩的指南,但该示例显示了它在 C++ 上的用法。在搜索了使用 SetWindowHookEx
的参考资料后,我阅读了关于处理低级别 windows 挂钩的示例。这些钩子,即 WH_KEYBOARD_LL
和 WH_MOUSE_LL
,是最常见的教程,可以全局挂钩,无需将它们的 Hook Process 分离到一个 dll 中。 WH System Events
的其余部分如果要全局挂钩则需要分离。文档中也对此进行了描述:
You must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle to the DLL module before it can install the hook procedure.
背后的粗略想法是将钩子函数注入所有 运行 线程。对于使用 User32.dll
作为其钩子库的 WH_KEYBOARD_LL
和 WH_MOUSE_LL
的情况,这很好。但是如果你像我一样将它用于其他系统事件,这个过程可能会像我的那样使你的整个桌面崩溃。
我的应用程序是用 C# 编写的,所以我必须用 C++ 创建一个 dll,然后 link 它到我的 C# 应用程序。另外,阅读 pInvokes
以能够使用 LoadLibrary
和 GetProcAddress
您可以从 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);
}
我正在开发一个在全球范围内监听触摸事件的应用程序,我已经为它设置了一个钩子来检索 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 上阅读了有关设置全局挂钩的信息。
我还调用了我的应用 window 的
RegisterTouchWindow
函数来启用接收触摸事件。
我会尽可能详细地回答我的问题,以便其他初学者了解发生了什么。
首先,我遵循了有关如何从 MSDN Hook Documentation 创建挂钩的指南,但该示例显示了它在 C++ 上的用法。在搜索了使用 SetWindowHookEx
的参考资料后,我阅读了关于处理低级别 windows 挂钩的示例。这些钩子,即 WH_KEYBOARD_LL
和 WH_MOUSE_LL
,是最常见的教程,可以全局挂钩,无需将它们的 Hook Process 分离到一个 dll 中。 WH System Events
的其余部分如果要全局挂钩则需要分离。文档中也对此进行了描述:
You must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle to the DLL module before it can install the hook procedure.
背后的粗略想法是将钩子函数注入所有 运行 线程。对于使用 User32.dll
作为其钩子库的 WH_KEYBOARD_LL
和 WH_MOUSE_LL
的情况,这很好。但是如果你像我一样将它用于其他系统事件,这个过程可能会像我的那样使你的整个桌面崩溃。
我的应用程序是用 C# 编写的,所以我必须用 C++ 创建一个 dll,然后 link 它到我的 C# 应用程序。另外,阅读 pInvokes
以能够使用 LoadLibrary
和 GetProcAddress
您可以从 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);
}