WriteConsoleInput (kernel32)
Last changed: -79.206.152.209

.
Summary

C# Signature:

    /* Writes data directly to the console input buffer. */
    [DllImport("kernel32.dll", EntryPoint = "WriteConsoleInputW", CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern bool WriteConsoleInput(
        IntPtr hConsoleInput,
        INPUT_RECORD[] lpBuffer,
        uint nLength,
        out uint lpNumberOfEventsWritten);

User-Defined Types:

C#

    // Code analysis will bring errors, but things here work
    // This is because i have the flag definitions inside the structs but ignore them through field offsets
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct INPUT_RECORD
    {
        public const ushort KEY_EVENT = 0x0001,
        MOUSE_EVENT = 0x0002,
        WINDOW_BUFFER_SIZE_EVENT = 0x0004;
        [FieldOffset(0)]
        public ushort EventType;

        // These are a union
        [FieldOffset(4)]
        public KEY_EVENT_RECORD KeyEvent;

        [FieldOffset(4)]
        public MOUSE_EVENT_RECORD MouseEvent;

        [FieldOffset(4)]
        public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;

        /*
        MENU_EVENT_RECORD MenuEvent;
        FOCUS_EVENT_RECORD FocusEvent; */
        // MSDN claims that these are used internally and shouldn't be used
        // https://docs.microsoft.com/en-us/windows/console/input-record-str

    }

    [StructLayout(LayoutKind.Sequential)]
    public struct COORD
    {
        public short X;
        public short Y;

        public COORD(short x, short y)
        {
        X = x;
        Y = y;
        }
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct MOUSE_EVENT_RECORD
    {
        [FieldOffset(0)]
        public COORD dwMousePosition;

        public const int DOUBLE_CLICK = 0x0002,
        MOUSE_HWHEELED = 0x0008,
        MOUSE_MOVED = 0x0001,
        MOUSE_WHEELED = 0x0004;
        [FieldOffset(4)]
        public uint dwButtonState;

        public const int CAPSLOCK_ON = 0x0080,
        ENHANCED_KEY = 0x0100,
        LEFT_ALT_PRESSED = 0x0002,
        LEFT_CTRL_PRESSED = 0x0008,
        NUMLOCK_ON = 0x0020,
        RIGHT_ALT_PRESSED = 0x0001,
        RIGHT_CTRL_PRESSED = 0x0004,
        SCROLLLOCK_ON = 0x0040,
        SHIFT_PRESSED = 0x0010;
        [FieldOffset(8)]
        public uint dwControlKeyState;

        public const int FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001,
        FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004,
        FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008,
        FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010,
        RIGHTMOST_BUTTON_PRESSED = 0x0002;
        [FieldOffset(12)]
        public uint dwEventFlags;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct KEY_EVENT_RECORD
    {
        [FieldOffset(0)]
        public bool bKeyDown;
        [FieldOffset(4)]
        public ushort wRepeatCount;
        [FieldOffset(6)]
        public ushort wVirtualKeyCode;
        [FieldOffset(8)]
        public ushort wVirtualScanCode;
        [FieldOffset(10)]
        public char UnicodeChar;
        [FieldOffset(10)]
        public byte AsciiChar;

        public const int CAPSLOCK_ON = 0x0080,
        ENHANCED_KEY = 0x0100,
        LEFT_ALT_PRESSED = 0x0002,
        LEFT_CTRL_PRESSED = 0x0008,
        NUMLOCK_ON = 0x0020,
        RIGHT_ALT_PRESSED = 0x0001,
        RIGHT_CTRL_PRESSED = 0x0004,
        SCROLLLOCK_ON = 0x0040,
        SHIFT_PRESSED = 0x0010;
        [FieldOffset(12)]
        public uint dwControlKeyState;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct WINDOW_BUFFER_SIZE_RECORD
    {
        [FieldOffset(0)]
        public COORD dwSize;
    }

Notes:

The only practical usage for this i've found is for debugging code reliant on ReadConsoleInput.

Please add if you've found something else that's useful

Tips & Tricks:

Please add some!

Sample Code:

    [DllImport("kernel32")]
    public static extern IntPtr GetStdHandle(StdHandle index);

    public enum StdHandle
    {
    OutputHandle = -11,
    InputHandle = -10,
    ErrorHandle = -12
    }

    static void Main(string[] args)
    {
    INPUT_RECORD[] record = new INPUT_RECORD[1];

    record[0].EventType = INPUT_RECORD.KEY_EVENT;

    record[0].KeyEvent = new KEY_EVENT_RECORD();
    record[0].KeyEvent.UnicodeChar = 'a';
    record[0].KeyEvent.AsciiChar = (byte)'a';
    record[0].KeyEvent.bKeyDown = true;

    uint recordsWritten = 0;
    bool boi = WriteConsoleInput(GetStdHandle(StdHandle.InputHandle), record, 1, out recordsWritten);
    }

Alternative Managed API:

Do you know one? Please contribute it!

Documentation