SetWindowsHookEx in C#

╄→尐↘猪︶ㄣ 提交于 2019-11-27 01:13:30

SetWindowsHookEx specifics the last two parameters thusly:

  • hMod

[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.

  • dwThreadId

[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.

I'm not sure you can use a .NET dll in the manner required, but you can certainly try.

Grab hMod via Marshal.GetHINSTANCE(typeof(Form1).Module) and dwThreadId via Process.Threads. Alternatively, set dwThreadId to 0 if you want a global hook (ie. a hook for all GetMessage() calls in the current desktop) but beware of the performance penalties.

BillVo

The following suggests this won't work:

"Global hooks are not supported in the .NET Framework. Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework."

From "How to set a Windows hook in Visual C# .NET"

I believe you need to P/Invoke GetModuleHandle and use the handle it returns for the third parameter of SetWindowsHookEx. I also believe 0 is correct for the fourth parameter, as you don't want to hook any one specific thread in the third-party application.

If this doesn't work for you, SetWindowsHookEx on MSDN might point you in the right direction.

I don't know but if you're using parameter values which specify that you want to, as the API helps says, "inject a DLL into another process", then for all I know it might work only if you write an unmanaged DLL from which to call it.

gumenimeda

I know that this is an old question but I'm hoping that there is still someone who will find this useful. I think that you are mixing up int and IntPtr

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
Kirk Patrick Brown

This work for me use 13...

 private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(13, proc,
                GetModuleHandle(curModule.ModuleName), 0);
            }
        }
  internal enum HookType : uint {
    WH_JOURNALRECORD = 0,
    WH_JOURNALPLAYBACK = 1,
    WH_KEYBOARD = 2,
    WH_GETMESSAGE = 3,
    WH_CALLWNDPROC = 4,
    WH_CBT = 5,
    WH_SYSMSGFILTER = 6,
    WH_MOUSE = 7,
    WH_HARDWARE = 8,
    WH_DEBUG = 9,
    WH_SHELL = 10,
    WH_FOREGROUNDIDLE = 11,
    WH_CALLWNDPROCRET = 12,
    WH_KEYBOARD_LL = 13,
    WH_MOUSE_LL = 14
  }

Global hooks are not supported in the .NET Framework

Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework.

To install a global hook, a hook must have a native DLL export to inject itself in another process that requires a valid, consistent function to call into. This behavior requires a DLL export.

The .NET Framework does not support DLL exports. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.

Low-level hook procedures are called on the thread that installed the hook. Low-level hooks do not require that the hook procedure be implemented in a DLL.

See also: Snoop - The WPF Spy Utility

Or my WPF => WF => Win32 LL_Keyboard Hook Proxy w/ Gestures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!