C# 在Windows XP中使用SetWindowsHookEx时出错,但在Windows 7中不使用

C# 在Windows XP中使用SetWindowsHookEx时出错,但在Windows 7中不使用,c#,winapi,hook,keyboard-hook,setwindowshookex,C#,Winapi,Hook,Keyboard Hook,Setwindowshookex,我开发了一个使用全局键盘/鼠标挂钩的应用程序。它在Windows7中工作得很好,但在WindowsXP中却不行 在Windows XP中调用SetWindowsHookEx时,得到错误代码1428 int MouseLowLevel = 14 int code = SetWindowsHookEx(MouseLowLevel, MouseHookProc, IntPtr.Zero, 0);

我开发了一个使用全局键盘/鼠标挂钩的应用程序。它在Windows7中工作得很好,但在WindowsXP中却不行

在Windows XP中调用SetWindowsHookEx时,得到错误代码1428

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

private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam) {}

奇怪的是,这段代码在Win7上没有失败,但我肯定从未尝试过。但这是正确的行为,看起来他们改进了。SetWindowsHookEx()的参数验证需要有效的非零第三个或第四个参数。错误代码是高度描述性的,来自WinError.h:

//
// MessageId: ERROR_HOOK_NEEDS_HMOD
//
// MessageText:
//
// Cannot set nonlocal hook without a module handle.
//
#define ERROR_HOOK_NEEDS_HMOD            1428L
任何模块句柄都可以,因为它实际上不用于低级钩子,所以不需要注入DLL使它们工作。由于.NET 4的CLR不再伪造纯托管程序集的模块句柄,因此需要谨慎选择一个。使用pinvoking LoadLibrary(“user32.dll”)中的一个很好的方法,因为它总是已经加载。您不必调用FreeLibrary()

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

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

非常感谢您的精彩回复。现在它可以在Windows 7和XP上运行。您的代码中还有另一个错误,SetWindowsHookEx()的返回类型是IntPtr,而不是int.oops,我在简化代码时犯了一些错误。在实际代码中,我使用了一个从SafeHandleZeroOrMinusOneIsInvalid继承的类。但是当我附加代码时,我不想看到太多细节。但无论如何还是要感谢:-)我原以为
GetModuleHandle(“kernel32.dll”)
会是一个更明显的选择。最不奇怪的原则是,SetWindowsHookEx需要使用user32.dll的pinvoke声明