当前位置: 首页 > 知识库问答 >
问题:

C#SendInput Alt/Ctrl/Shift键未释放

鲁乐
2023-03-14

我使用下面的代码通过sendinput传递特殊键。我正面临一个奇怪的问题。如果用户发送Alt//Ctrl/Shift,则键保持按下状态。例如,如果用户通过Alt+F4,代码正常运行,操作成功完成,但Alt键保持按下状态。我需要在操作完成后手动单击Alt键。请让我知道处理同样的代码本身。下面是用于发送特殊密钥的代码

namespace RemoteDesktopSendKeys
{
class Program
{
       struct INPUT
    {
        public INPUTType type;
        public INPUTUnion Event;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct INPUTUnion
    {
        [FieldOffset(0)]
        internal MOUSEINPUT mi;
        [FieldOffset(0)]
        internal KEYBDINPUT ki;
        [FieldOffset(0)]
        internal HARDWAREINPUT hi;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct MOUSEINPUT
    {
        public int dx;
        public int dy;
        public int mouseData;
        public int dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct KEYBDINPUT
    {
        public ushort wVk;
        public ushort wScan;
        public KEYEVENTF dwFlags;
        public int time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct HARDWAREINPUT
    {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    }

    enum INPUTType : uint
    {
        INPUT_KEYBOARD = 1
    }

    [Flags]
    enum KEYEVENTF : uint
    {
        EXTENDEDKEY = 0x0001,
        KEYUP = 0x0002,
        SCANCODE = 0x0008,
        UNICODE = 0x0004
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern UInt32 SendInput(int numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
    [DllImport("user32.dll")]
    public static extern IntPtr GetMessageExtraInfo();
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
    private const int KEYEVENTF_KEYUP1 = 0x0002;

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

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    internal static extern int MapVirtualKey(int uCode, int uMapType);


    static void Main(string[] args)
    {
        Thread.Sleep(3000);
          int[] keyboardStrokes = { (int)Keys.LMenu,(int)Keys.F4 };

        //int[] keyboardStrokes = { (int)Keys.ControlKey, (int)Keys.A };


        SendSpecialKeys("test", keyboardStrokes);

        //SendSpecialKeys("F5",keyboardStrokes);
    }

    private static void SendSpecialKeys(string text, int[] modifiers)
    {

        List<int> arrKeys = new List<int>();
        Keys key;

        if (modifiers != null && modifiers.Length > 0)
        {
            for (int i = 0; i < modifiers.Length; i++)
            {
                arrKeys.Add(modifiers[i]);
            }
        }

        if (!string.IsNullOrEmpty(text))
        {
            if (Enum.TryParse(text, out key))
                arrKeys.Add((int)key);
            else
                SendText(text);
        }

        System.Threading.Thread.Sleep(1000);
        int[] arrKeyStrokes = arrKeys.ToArray();
        INPUT[] inputs = new INPUT[arrKeyStrokes.Length + 1];

        for (int i = 0; i < arrKeyStrokes.Length; i++)
        {
            uint skey = MapVirtualKey((uint)arrKeyStrokes[i], (uint)0x0);
            inputs[i].type = INPUTType.INPUT_KEYBOARD;
            inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
            inputs[i].Event.ki.wScan = (ushort)skey;
        }

        inputs[arrKeyStrokes.Length].type = INPUTType.INPUT_KEYBOARD;
        inputs[arrKeyStrokes.Length].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
        inputs[arrKeyStrokes.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;

        SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));

    }
    public static void SendText(string text)
    {
        List<INPUT> kbInput = new List<INPUT>();

        foreach (char c in text)
        {
            // Send a key down followed by key up.
            foreach (bool keyUp in new bool[] { false, true })
            {
                INPUT input = new INPUT
                {
                    type = INPUTType.INPUT_KEYBOARD,
                    Event = new INPUTUnion
                    {
                        // This will contain keyboard event information
                        ki = new KEYBDINPUT
                        {
                            wVk = 0,
                            wScan = c,
                            dwFlags = KEYEVENTF.UNICODE | (keyUp ? KEYEVENTF.KEYUP : 0),
                            dwExtraInfo = GetMessageExtraInfo(),
                        }
                    }
                };

                kbInput.Add(input);
            }
        }

        // Call SendInputWindows API to send input
        SendInput((int)kbInput.Count, kbInput.ToArray(), Marshal.SizeOf(typeof(INPUT)));
    }
}

}

共有1个答案

丁念
2023-03-14

下面的代码可以用来释放特定的键。下面是释放控制键的示例代码。

    uint ctrlkey = MapVirtualKey((uint)Keys.ControlKey, (uint)0x0);
                inputs[index].type = INPUTType.INPUT_KEYBOARD;
                inputs[index].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
                inputs[index].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
                inputs[index].Event.ki.wScan = (ushort)ctrlkey;

需要确保通过正确传递索引释放正确的键。

 类似资料:
  • 这在Python中似乎很难。 目前,我只能使用sys.stdin.read()读取击键,但是stdin.read()像文件一样工作,不会返回修饰符。 我在函数返回击键组合的方式上很灵活。首先想到的是返回一个列表或一个带有组合的dict…但主要问题是,如何检测它?!

  • 我试图编码一个简单的键盘,并想实现上述4个键。在我的文件中,我定义了如下的布局- 我一直在中使用ASCII代码。但是我不知道如何处理Ctrl、Alt、Delete和Shift键。我使用作为backspace。但不确定如何实现delete键。 编辑:如果有人能在箭头键上加入一些指针,那也会很有帮助。

  • 问题内容: 我怎么能确定 哪个 / / 下面的代码键被按下? 问题答案: 好吧,这仅适用于IE 8,因此无法在所有浏览器中使用。Microsoft实现了确定按下哪个(右/左)键的功能。 我也发现这篇关于浏览器中的按键,按键,按键事件的奇妙文章。

  • 问题内容: 我试图获得一个+ 和+ + 绑定在tmux会话中工作(我也在使用PuTTY)。 我已经经历了必须重新编译PuTTY的痛苦,以便它能够正确发送和发送。使用+之后,我能够看到并分别发送给+ 和+ + 。有什么办法可以将这些绑定到tmux内部的下一个窗口和上一个窗口? 编辑:经过一些研究,我想我可能必须配置xterm来包括那些键码。知道我该怎么做吗? Edit2:所以我发现我可以检索info

  • 本文向大家介绍JS实现屏蔽shift,Ctrl,alt等功能键的方法,包括了JS实现屏蔽shift,Ctrl,alt等功能键的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS实现屏蔽shift,Ctrl,alt等功能键的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的javascript程序设计有所帮助。

  • JavaFX8控制器如何判断Shift、Ctrl、Alt或Enter键位于键盘的左边还是右边? 尝试使用JNativeHook(他们最近移动了),它几乎可以作为一个解决方案,但不能识别一些键,时间不精确,实现起来有点笨拙,尤其是因为我不能为所有平台编译本机代码。许可条款也有点混乱(稳定版本的GPL,在我的情况下不是一个选项,可能会转向LGPL...)。