简体   繁体   English

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

[英]C# SendInput Alt/Ctrl/Shift Keys not getting Released

I am using the below code to pass special keys using SendInput . 我正在使用下面的代码使用SendInput传递特殊键。 I am facing one strange issue. 我面临一个奇怪的问题。 If user sends any of Alt / Ctrl / Shift , the key remains pressed eg if user passes Alt + F4 , the code runs properly and action is completed successfully but Alt key remains pressed. 如果用户发送Alt / Ctrl / Shift中的任何一个,则该键将保持按下状态,例如,如果用户通过Alt + F4 ,则代码将正常运行并且操作成功完成,但Alt键将保持按下状态。 I need to manually click Alt key after the operation is completed. 操作完成后,我需要手动单击Alt键。 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)));
    }
}

} }

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. 需要确保通过正确传递索引来释放正确的密钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM