b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

c#模拟键盘 大部分游戏不响应消息的真正原因在这里!!

电脑杂谈  发布时间:2021-02-20 00:03:36  来源:网络整理

1.使用.Net Framework的库函数

SendKeys.SendWait("123{TAB}abc");

System.Windows.Forms命名空间下的

SendKeys是用于模拟.Net提供的键盘输入的工具。有两种方法,Send()和SendWait(),这两种方法都可以发送关键消息。不同之处在于,SendWait()将在返回之前等待关键消息的处理,而Send()则不会。这类似于SendMessage和PostMessage之间的关系。

上面的代码中的

{TAB}表示Tab键。键盘上的一些特殊键具有相应的代码,具体的比较表可以参考Microsoft MSDN上的介绍:SendKeys类

当然,您也可以使用Windows API,该API原型如下:

        /// 
        /// 合成一次击键事件
        /// 
        /// 定义一个虚拟键码。键码值必须在1~254之间
        /// 定义该键的硬件扫描码
        /// 定义函数操作的各个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位
        /// 定义与击键相关的附加的32位值
        [DllImport("user32")]
        public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, 
uint dwExtraInfo);

甚至可以使用SendMessage和PostMessage完成。

但是,以上实现方法都是Windows消息级别的,对于常规应用程序(如记事本)而言,这没有问题。但这对于某些游戏,QQ登录框,网上银行登录框等无效。这是因为这些程序不是从Windows消息中获取关键信息,而是直接从底层驱动程序级别获取关键信息。

在有关研究游戏插件的博客文章中,我看到博客描述了此问题:

模拟键盘软件_joytokey模拟键盘_c#模拟键盘

引用自:

在更详细地解释该原理之前,让我们抓住幕后黑手,看看哪个人在支持这场比赛?让它有胆量违抗Windows message命令。是否判断实际的键盘信息还是有其他原因?结果,我在DirectX编程中找到了DirectInput API。它绕过了Windows消息机制,其目的是使游戏的实时控制更好,更快。 Windows消息以队列的形式出现,并且传输过程中会有延迟。例如,格斗游戏对实时控制有很高的要求,而窗口消息机制不能满足这一要求。而且DirectInput直接与键盘驱动程序打交道,当然,效率要高得多。我认为大多数游戏不响应消息的真正原因是在这里,而不是故意编写反作弊系统。

2.使用WinIO.dll

由于上述方法只能模拟Windows消息级别的按钮,因此对于某些应用程序无效,因此下面使用在驱动程序级别直接模拟按钮的方法。

这里需要使用一个组件,即WinIO.dll,它是由外国大亨开发的dll。

引自百度百科:

WinIO库允许直接访问32位Windows应用程序中的I / O端口和物理内存。通过使用内核模式设备驱动程序和其他几种低级编程技术,它可以绕开Windows系统的保护机制。

使用此组件的环境要求:

如何在Windows中打开测试模式:

以管理员身份打开cmd,输入命令以打开测试模式并执行它。然后重新启动计算机,并在桌面的右下角看到“测试模式”字样。

打开测试模式的命令:

c#模拟键盘_joytokey模拟键盘_模拟键盘软件

bcdedit /set testsigning on

关闭测试模式的命令:

bcdedit /set testsigning off

成功打开测试模式:

成功打开测试模式

调用WinIO6 4. dll的示例代码:

    public class WinIO64
    {
        private const int KBC_KEY_CMD = 0x64;
        private const int KBC_KEY_DATA = 0x60;
        #region WinIo64.dll
        [DllImport("WinIo64.dll")]
        public static extern bool InitializeWinIo();
        [DllImport("WinIo64.dll")]
        public static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, 
byte bSize);
        [DllImport("WinIo64.dll")]
        public static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte 
bSize);
        [DllImport("WinIo64.dll")]
        public static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, 
IntPtr PhysicalMemoryHandle);
        [DllImport("WinIo64.dll")]
        public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, 
byte pbLinAddr);
        [DllImport("WinIo64.dll")]
        public static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
        [DllImport("WinIo64.dll")]
        public static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
        [DllImport("WinIo64.dll")]
        public static extern void ShutdownWinIo();
        #endregion
        [DllImport("user32.dll")]
        public static extern int MapVirtualKey(uint Ucode, uint uMapType);
        private WinIO64()
        {
            IsInitialize = true;
        }
        public static void Initialize()
        {
            if (InitializeWinIo())
            {
                KBCWait4IBE();
                IsInitialize = true;
            }
            else
                MessageBox.Show("Load WinIO Failed!");
        }
        public static void Shutdown()
        {
            if (IsInitialize)
                ShutdownWinIo();
            IsInitialize = false;
        }
        private static bool IsInitialize { get; set; }
        ///等待键盘缓冲区为空
        private static void KBCWait4IBE()
        {
            int dwVal = 0;
            do
            {
                bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
            }
            while ((dwVal & 0x2) > 0);
        }
        /// 模拟键盘标按下
        public static void KeyDown(Keys vKeyCoad)
        {
            if (!IsInitialize) return;
            int btScancode = 0;
            btScancode = MapVirtualKey((uint)vKeyCoad, 0);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);
        }
        /// 模拟键盘弹出
        public static void KeyUp(Keys vKeyCoad)
        {
            if (!IsInitialize) return;
            int btScancode = 0;
            btScancode = MapVirtualKey((uint)vKeyCoad, 0);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
            KBCWait4IBE();
            SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);
        }
    }
}

3.使用WinRing0x6 4. dll

还有另一个组件WinRing0x6 4. dll,可以实现相同的效果。无需授权签名,无需打开测试模式,使用更加方便。

使用此组件的环境要求:

模拟键盘软件_c#模拟键盘_joytokey模拟键盘

调用此组件的示例代码有点长,因此我不必在这里发布它。

对于2和3的两种方法,我编写了一个完整而可行的Demo并将其放在GitHub上。包括所需的组件都在里面。

链接:

模拟键盘输入的演示

URL地址:

收集的参考资料摘要:

爬行者对银行的安全控制措施做出反应

驱动程序级键盘模拟(C#)

C#模拟鼠标和键盘操作

Windows下硬件端口的操作--- WinIo库的使用

WinIo使用说明


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-359046-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 鲁孝公姬夷宫
        鲁孝公姬夷宫

        萨达姆是民选合法总统

      • 杰西卡
        杰西卡

        至少缩水1000以上

      热点图片
      拼命载入中...