C# .net sendkeys 不使用 SendKey() 而是使用挂钩

Posted

技术标签:

【中文标题】C# .net sendkeys 不使用 SendKey() 而是使用挂钩【英文标题】:C# .net send keys NOT using SendKey() but rather with hooking mabye 【发布时间】:2016-10-15 15:41:21 【问题描述】:

在我的具体情况下,我正在尝试创建一个将键盘击键发送到 DosBox(dos-games 模拟器,而不是 windows 命令提示符)的应用程序。

我尝试使用 SendKeys 执行此操作,但这不起作用,因为 DosBox 不是处理 windows 消息的应用程序(一个例外告诉我)。

目前我正在尝试使用键盘挂钩来做到这一点,如下所示: 第一种方法是接收钩子击键并将它们传递到下一个应用程序(如this example)

    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    
        return CallNextHookEx(hookId, nCode, wParam, lParam); 
    

    private void GenerateKeyPress()
    
        int vkCode = (int)Keys.Up;    //My chosen key to be send to dosbox
        IntPtr lParam = new IntPtr(vkCode); 
        IntPtr wParam = new IntPtr(255);

        CallNextHookEx(hookId, 0, wParam, lParam);
    

CallNextHookEx() 函数调用会引发访问冲突异常。

在这里我需要考虑什么?

【问题讨论】:

【参考方案1】:

我认为你应该使用“keybd_event”来代替“SendKeys”。

public static class Keyboard

    public static void Press(Keys keys, int sleep = 1)
    
        var keyValue = (byte)keys;

        NativeMethods.keybd_event(keyValue, 0, 0, UIntPtr.Zero); //key down

        Thread.Sleep(sleep);

        NativeMethods.keybd_event(keyValue, 0, 0x02, UIntPtr.Zero); //key up
    


internal static partial class NativeMethods

    [DllImport("user32.dll")]
    internal static extern void keybd_event(byte bVk, byte bScan, int dwFlags, UIntPtr dwExtraInfo);

【讨论】:

【参考方案2】:

访问冲突是由LPARAM 为low-level keyboard hook 造成的,即用

创建的
SetWindowsHookEx(WH_KEYBOARD_LL,...)

是指向KBDLLHOOKSTRUCT 的指针,而不是伪装成指针的键码。您正在告诉钩子链中的下一个钩子访问任意内存位置。 (另外,WPARAM 应该是WM_KEYDOWNWM_KEYUPWM_SYSKEYDOWNWM_SYSKEYUP 之一。)

您链接的示例代码使用Marshal.ReadInt32(lParam) 获取关键代码,这实际上是读取指针引用的结构中的第一个整数。

就您要完成的工作而言,方法是使用SendInput 这是一个主题been covered here so so many times @ 987654330@itdoesnotbearrepeating.


(这还不是所有的 SendInput 问题)

【讨论】:

以上是关于C# .net sendkeys 不使用 SendKey() 而是使用挂钩的主要内容,如果未能解决你的问题,请参考以下文章

C# WinForm程序怎么用代码控制 浏览器 后退和向前

C# 模拟键盘操作SendKey(),SendKeys() / C# SendKeys用法

C# SendKeys用法

.NET 模拟 Ctrl+Alt+Del 发送键

无法使用 (SendKeys.Send) 粘贴字符串

SendKeys.Send()的使用 转