SetWindowsHookEx возвращает 0 при компиляции для .NET 4.0 framework на 32-битных машинах - PullRequest
7 голосов
/ 25 августа 2010

Я пытаюсь установить низкоуровневую клавиатуру Windows для захвата трех нажатых клавиш, даже если приложение не в фокусе.Для этого я вызываю SetWindowsHookEx как

// Create an instance of HookProc.
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
//install hook
hKeyboardHook = SetWindowsHookEx(
    WH_KEYBOARD_LL,
    KeyboardHookProcedure,
    Marshal.GetHINSTANCE(
        Assembly.GetExecutingAssembly().GetModules()[0]),
    0);
//If SetWindowsHookEx fails.
if (hKeyboardHook == 0)
{
    //Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set. 
    int errorCode = Marshal.GetLastWin32Error();
    //do cleanup
    Stop(false, true, false);
    //Initializes and throws a new instance of the Win32Exception class with the specified error. 
    throw new Win32Exception(errorCode);
}

. Раньше он работал на 32-битных и 64-битных машинах с использованием .NET Framework 3.5, но после обновления до .NET Framework 4.0 перестал работать на 32-битных машинах.*

Кто-нибудь знает, как решить эту проблему, чтобы я мог использовать 4.0 Framework и заставить это работать как на 32-битных, так и на 64-битных машинах?

Ответы [ 4 ]

23 голосов
/ 29 июня 2012

импортировать dll следующим образом:

[DllImport("kernel32.dll")]
    public static extern IntPtr GetModuleHandle(string name); 

затем используйте

GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)

заменить

Marshal.GetHINSTANCE(
    Assembly.GetExecutingAssembly().GetModules()[0]
2 голосов
/ 22 сентября 2010

Из документации для SetWindowsHookEx

hMod [in]
HINSTANCE
Дескриптор библиотеки DLL, содержащейподключаемая процедура, указанная параметром lpfn.Параметр hMod должен быть установлен в NULL, если параметр dwThreadId указывает поток, созданный текущим процессом, и если подключаемая процедура находится в коде, связанном с текущим процессом.

Таким образом, вы должны передать IntPtr.Zero для NULL

//install hook
  hKeyboardHook = SetWindowsHookEx(
    WH_KEYBOARD_LL,
    KeyboardHookProcedure,
    IntPtr.Zero,
    0);
1 голос
/ 30 августа 2010

Решено, ориентируясь на каждую платформу отдельно.Настроил VS для компиляции версий Win32 и Win64 и развертывания на машинах x86 и x64 их соответствующих двоичных файлов.

Win32 или x86 работает как на 32-битных, так и на 64-битных машинах.

0 голосов
/ 20 февраля 2014

Ганс Пассант :

Подойдет любой дескриптор модуля, так как он фактически не используется для низкоуровневые хуки, не нужно вводить DLL, чтобы они работали. Немного Тщательный выбор необходим для .NET 4, так как его CLR больше не требуется. фальшивые дескрипторы модулей для чисто управляемых сборок. Хороший, чтобы использовать это тот, который вы получаете из pinvoking LoadLibrary ("user32.dll"), так как это всегда уже загружен. Вам не нужно вызывать FreeLibrary ().

Вам понадобится это объявление для вызова LoadLibrary:

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