通过远程桌面发送特殊密钥

时间:2014-11-28 10:45:23

标签: c# rdp sendinput

我可以在本地计算机上发送特殊密钥,但同样的事情不能在远程计算机上运行。我提到了许多文章,但找不到将特殊密钥发送到远程桌面连接的代码。请帮忙。以下是代码。

 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();
        }
    }

提前致谢。

1 个答案:

答案 0 :(得分:0)

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

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)));
    }

}