挂钩键盘:如何获取按下该键的程序的名称?

发布于 2025-01-07 23:51:21 字数 2485 浏览 0 评论 0原文

我用 C# 做了一个简单的钩子键盘,所以我有以下代码:

        private static IntPtr hKeyboardHook = IntPtr.Zero;
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x100;

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr 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, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int UnhookWindowsHookEx(IntPtr idHook);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("user32")]
        private static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
        [DllImport("user32")]
        private static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern short GetKeyState(int vKey);
        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string lpModuleName);
        private static LowLevelKeyboardProc _proc = HookCallback;

 public void initialization()
        {
            using (Process curProcess = Process.GetCurrentProcess())
                using (ProcessModule curModule = curProcess.MainModule)
                {
                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, GetModuleHandle(curModule.ModuleName), 0);
                }  
        }

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            if (vkCode >= 32 && vkCode < 160)
                Console.Write((Keys)vkCode);
            if (vkCode == 13)
                Console.WriteLine("\n");
        }
        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
    }

它工作正常,没有问题!我的程序抓住其他程序中按下的所有键并将其写在控制台上。 但我想知道按下按键的程序的名称,但我不知道该怎么做。

任何人都可以帮助我吗?

I made a simple hook keyboard in C#, so i have this following code :

        private static IntPtr hKeyboardHook = IntPtr.Zero;
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x100;

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr 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, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int UnhookWindowsHookEx(IntPtr idHook);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("user32")]
        private static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
        [DllImport("user32")]
        private static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern short GetKeyState(int vKey);
        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string lpModuleName);
        private static LowLevelKeyboardProc _proc = HookCallback;

 public void initialization()
        {
            using (Process curProcess = Process.GetCurrentProcess())
                using (ProcessModule curModule = curProcess.MainModule)
                {
                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, GetModuleHandle(curModule.ModuleName), 0);
                }  
        }

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            if (vkCode >= 32 && vkCode < 160)
                Console.Write((Keys)vkCode);
            if (vkCode == 13)
                Console.WriteLine("\n");
        }
        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
    }

It works fine with no problem !! my program grip all key pressed in other program and write it on the console.
But i want to have the name of the program where the key is pressed, and i don't know how i can do that.

Anyone can help me ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清泪尽 2025-01-14 23:51:21

您正在使用低级挂钩 (WH_KEYBOARD_LL)。在窗口管理器决定哪个程序将接收消息之前调度低级挂钩。因此,不存在“按下按键的程序的名称”,因为窗口管理器尚未决定按键将被传递到哪个程序。 (你可以通过调用GetForegroundWindow来尝试猜测。)

(只是好奇:你试图使用键盘钩子解决的最终问题是什么?也许有更好的方法。我希望你是不写键盘记录器。)

You are using a low-level hook (WH_KEYBOARD_LL). Low-level hooks are dispatched before the window manager decides which program will receive the message. Therefore, there is no "name of the program where the key is pressed" because the window manager hasn't yet decided which program the keypress will be delivered to. (You can try to guess by calling GetForegroundWindow.)

(Just curious: What is the ultimate problem you're trying to solve by using a keyboard hook? Maybe there's a better way. I hope you're not writing a keylogger.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文