在Windows XP中使用SetWindowsHookEx时出错,但在Windows 7中没有

mag*_*gol 5 c# hook winapi keyboard-hook setwindowshookex

我开发了一个使用全局键盘/鼠标钩子的应用程序.它在Windows 7中运行良好,但在Windows XP中运行不佳.

当我在Windows XP中调用SetWindowsHookEx时,我收到错误代码1428

int MouseLowLevel   = 14
int code = SetWindowsHookEx(MouseLowLevel,
                 MouseHookProc,
                 IntPtr.Zero,
                 0);

private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam) {}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 11

好奇这个代码在Win7上没有失败,但我当然没试过.但这是正确的行为,看起来他们改进了它.SetWindowsHookEx()的参数验证需要有效的非零第3或第4个参数.WinError.h中的错误代码是高度描述性的:

//
// MessageId: ERROR_HOOK_NEEDS_HMOD
//
// MessageText:
//
// Cannot set nonlocal hook without a module handle.
//
#define ERROR_HOOK_NEEDS_HMOD            1428L
Run Code Online (Sandbox Code Playgroud)

任何模块句柄都可以,因为它实际上并没有用于低级钩子,不​​需要注入DLL来使它们工作..NET 4需要注意选择一个,因为它的CLR不再伪造纯托管程序集的模块句柄.一个好用的是你可以用它来加载LoadLibrary("user32.dll"),因为它总是已经加载了.您不必调用FreeLibrary().

您需要此声明才能调用LoadLibrary:

[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string fileName);
Run Code Online (Sandbox Code Playgroud)

  • 您的代码中还有另一个错误,SetWindowsHookEx()的返回类型是IntPtr,而不是int. (2认同)
  • 我原以为`GetModuleHandle("kernel32.dll")`本来是一个更明显的选择. (2认同)