简体   繁体   English

C#.net 3.5中冻结的全局低级键盘挂钩

[英]Global low level keyboard hook freezing in c# .net 3.5

i have a frustrating problem with registering global hook. 我在注册全局钩子时遇到一个令人沮丧的问题。 I am using this class in my windows application: 我在Windows应用程序中使用此类:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

class InterceptKeys
{
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

    public static void Hook()
    {
        _hookID = SetHook(_proc);
    }

    private static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                GetModuleHandle(curModule.ModuleName), 0);
        }
    }

    private delegate IntPtr LowLevelKeyboardProc(
        int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            MessageBox.Show("Test");
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

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

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

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

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
}

Here is Program.cs 这是Program.cs

namespace TestHooks
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            InterceptKeys.Hook();
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

    }
}

Everything works (MessageBox pops up) but windows freezes for a moment and beeper beeps. 一切正常(弹出MessageBox),但窗口冻结片刻,并发出蜂鸣声。 The problem doesn't occur on Windows 7 just on Vista. 仅在Vista上的Windows 7上不会发生此问题。 Any suggestions please? 有什么建议吗?

You cannot use MessageBox in your code. 您不能在代码中使用MessageBox。 It blocks execution, the keyboard goes dead. 它阻止执行,键盘失效。 Use Console.WriteLine() for example, output goes to the Visual Studio Output window. 例如,使用Console.WriteLine(),输出将转到“ Visual Studio输出”窗口。

Beware that this code won't work anymore on .NET 4.0, GetModuleHandle() will return NULL. 请注意,此代码在.NET 4.0上将不再起作用,GetModuleHandle()将返回NULL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM