C# SendInput Alt/Ctrl/Shift Keys not getting Released

本小妞迷上赌 提交于 2019-12-24 12:44:14

问题


I am using the below code to pass special keys using SendInput. I am facing one strange issue. If user sends any of Alt/Ctrl/Shift, the key remains pressed e.g. if user passes Alt + F4, the code runs properly and action is completed successfully but Alt key remains pressed. I need to manually click Alt key after the operation is completed. Please let me know to handle the same in the code itself. Below is the code used to send special keys.

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:


The following code can be used to release particular key. Below is the sample code to release control key.

    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;

Need to make sure that proper key is released by passing index properly.



来源:https://stackoverflow.com/questions/27278399/c-sharp-sendinput-alt-ctrl-shift-keys-not-getting-released

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!