在C#中,SetWindowsHookEx似乎不适合我(WH_KEYBOARD_LL,全局)

Jak*_*urc 1 c# winapi setwindowshookex

每当用户按下窗口中的某些键时,我的应用程序应执行一些操作

SetWindowsHookEx使用WH_KEYBOARD_LL选项调用似乎是实现此目标的标准方法.但是在我的情况下,有些事情显然是错误的并且没有被解雇的回调.

调试控制台应用程序的主要方法:

static void Main(string[] args)
{
    IntPtr moduleHandle = GetCurrentModuleHandle();
    IntPtr hookHandle = IntPtr.Zero;

    try
    {
        User32.HookProc hook = (nCode, wParam, lParam) =>
        {
            // code is never called :-(
            if (nCode >= 0)
            {
                Console.WriteLine("{0}, {1}", wParam.ToInt32(), lParam.ToInt32());
            }
            return User32.CallNextHookEx(hookHandle, nCode, wParam, lParam);
        };

        hookHandle = User32.SetWindowsHookEx(User32.WH_KEYBOARD_LL, hook, moduleHandle, 0);

        Console.ReadLine(); // 
    }
    finally
    {
        if (hoodHandle != IntPtr.Zero)
        {
            var unhooked = User32.UnhookWindowsHookEx(hookHandle);
            Console.WriteLine(unhooked); // true
            hookHandle = IntPtr.Zero;                   
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

GetCurrentModuleHandle方法:

private static IntPtr GetCurrentModuleHandle()
{
    using (var currentProcess = Process.GetCurrentProcess())
    using (var mainModule = currentProcess.MainModule)
    {
        var moduleName = mainModule.ModuleName;
        return Kernel32.GetModuleHandle(moduleName);
    }           
}
Run Code Online (Sandbox Code Playgroud)

user32.dll和进口kernel32.dll:

public static class User32
{
    public const int WH_KEYBOARD_LL = 13;

    public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);        
}

public static class Kernel32
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetModuleHandle(string lpModuleName);
}
Run Code Online (Sandbox Code Playgroud)

你知道我的问题是什么吗?

Cyr*_*pta 5

无法从C#控制台应用程序调用SetwindowHook API.您需要在Windows DLL中调用它(它不能在.Net DLL中工作).

肯定有办法解决这个问题,我确实使用过很久以前我建立的应用程序之一.但我现在不记得了.你可以找出你是否搜索足够长的时间.