【问题标题】:Send Special Keys Over Remote Desktop通过远程桌面发送特殊密钥
【发布时间】:2014-11-28 10:45:23
【问题描述】:

我可以在本地机器上发送特殊密钥,但同样的事情在远程机器上不起作用。我参考了很多文章,但找不到将特殊键发送到远程桌面连接的代码。请帮助解决这个问题。下面是代码。

 static void Main(string[] args)
    {
        Thread.Sleep(3000);
        //char[] keyboardStrokes = { (char)Keys.LWin, (char)Keys.R };
        char[] keyboardStrokes = { (char)Keys.LMenu, (char)Keys.F4 };
        SendData(keyboardStrokes);

    }
    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 short wVk;
        public short 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")]
    static extern IntPtr GetMessageExtraInfo();

    private static void SendData(char[] c)
    {
        ProcessKey(c);
    }


    private static void ProcessKey(char[] key)
    {
        // create input events as unicode with first down, then up
        INPUT[] inputs = new INPUT[key.Length + 1];
        for (int i = 0; i < key.Length; i++)
        {
            inputs[i].type = INPUTType.INPUT_KEYBOARD;
            inputs[i].Event.ki.dwFlags = KEYEVENTF.UNICODE;
            inputs[i].Event.ki.wScan = (short)key[i];
            inputs[i].Event.ki.wVk = (short)key[i];
        }
        //Thread.Sleep(3000);
        inputs[key.Length].type = INPUTType.INPUT_KEYBOARD;
        inputs[key.Length].Event.ki.dwFlags = KEYEVENTF.KEYUP;
        inputs[key.Length].Event.ki.dwExtraInfo = GetMessageExtraInfo();
        // inputs[key.Length].Event.ki.wScan =
        // inputs[key.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
        uint cSuccess = SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
        if (cSuccess != inputs.Length)
        {
            throw new Win32Exception();
        }
    }

提前致谢。

【问题讨论】:

    标签: c# rdp sendinput


    【解决方案1】:

    最后,我可以使用以下代码将大部分特殊密钥发送到远程机器。唯一的问题是操作完成后特殊键仍然按下。请告诉我如何释放特殊键。

    class Program
    {
        static void Main(string[] args)
        {
            Thread.Sleep(3000);
            int[] keyboardStrokes = { (int)Keys.LMenu, (int)Keys.Tab, (int)Keys.Tab };
            ProcessKey(keyboardStrokes);
            Console.Read();
        }
        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);
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
    
        private static void ProcessKey(int[] key)
        {
            INPUT[] inputs = new INPUT[key.Length + 1];
            for (int i = 0; i < key.Length; i++)
            {
                uint skey = MapVirtualKey((uint)key[i], (uint)0x0);
                inputs[i].type = INPUTType.INPUT_KEYBOARD;
                inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
                inputs[i].Event.ki.wScan = (ushort)skey;
            }
            inputs[key.Length].type = INPUTType.INPUT_KEYBOARD;
            inputs[key.Length].Event.ki.dwFlags = KEYEVENTF.UNICODE;
            inputs[key.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
            uint cSuccess = SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
        }
    
    }
    

    【讨论】:

    • 您的代码错误。您必须使用 ONE SendKey() 键按下,然后暂停至少 10 毫秒,然后再使用另一个 SendKey() 键按下。所有这些都在每个键的 for() 循环中。
    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-11
    • 1970-01-01
    相关资源
    最近更新 更多