Любопытно, что этот код не провалится на 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. – magol
У вас есть еще одна ошибка в коде, возвращаемый тип для SetWindowsHookEx() - это IntPtr, а не int. –
oops, я сделал некоторые ошибки, когда я упростил код. В реальном коде я использую класс, который наследуется от SafeHandleZeroOrMinusOneIsInvalid. Но я не хотел слишком много деталей, когда я прикреплял код. Но спасибо в любом случае :-) – magol