using System.Collections.Generic;
using System.Runtime.InteropServices;
public static class KBEmulator
public static void Main(String[] args){
public enum InputType : uint
internal enum KEYEVENTF : uint
internal enum MOUSEEVENTF : uint
MOVE_NOCOALESCE = 0x2000,
[StructLayout(LayoutKind.Sequential)]
internal InputUnion Data;
return Marshal.SizeOf(typeof(lpInput));
[StructLayout(LayoutKind.Explicit)]
internal struct InputUnion
internal HARDWAREINPUT hi;
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
internal MOUSEEVENTF dwFlags;
internal UIntPtr dwExtraInfo;
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
internal KEYEVENTF dwFlags;
internal UIntPtr dwExtraInfo;
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
[DllImport("user32.dll", SetLastError = true)]
internal static extern uint SendInput(uint cInputs, [MarshalAs(UnmanagedType.LPArray)] lpInput[] inputs, int cbSize);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern short VkKeyScan(char ch);
internal static short VkKeyScan(char ch)
return unmanaged.VkKeyScan(ch);
internal static uint SendInput(uint cInputs, lpInput[] inputs, int cbSize)
return unmanaged.SendInput(cInputs, inputs, cbSize);
public static void SendScanCodeCombo(short[] scanCodes)
lpInput[] KeyInputs = new lpInput[1];
lpInput KeyInput = new lpInput();
Enum[] actions = {KEYEVENTF.KEYDOWN, KEYEVENTF.KEYUP};
KeyInput.type = InputType.INPUT_KEYBOARD;
KeyInput.Data.ki.wScan = 0;
KeyInput.Data.ki.time = 0;
KeyInput.Data.ki.dwExtraInfo = UIntPtr.Zero;
foreach (KEYEVENTF action in actions)
foreach (short scanCode in scanCodes)
KeyInput.Data.ki.wVk = scanCode;
KeyInput.Data.ki.dwFlags = action;
SendInput(1, KeyInputs, lpInput.Size);
public static void SendChars(char[] keys)
lpInput[] KeyInputs = new lpInput[1];
lpInput KeyInput = new lpInput();
Enum[] actions = {KEYEVENTF.KEYDOWN, KEYEVENTF.KEYUP};
KeyInput.type = InputType.INPUT_KEYBOARD;
KeyInput.Data.ki.wScan = 0;
KeyInput.Data.ki.time = 0;
KeyInput.Data.ki.dwExtraInfo = UIntPtr.Zero;
foreach (KEYEVENTF action in actions)
foreach (char ch in keys)
KeyInput.Data.ki.wVk = VkKeyScan(ch);
KeyInput.Data.ki.dwFlags = KEYEVENTF.KEYDOWN;
SendInput(1, KeyInputs, lpInput.Size);
KeyInput.Data.ki.dwFlags = KEYEVENTF.KEYUP;
SendInput(1, KeyInputs, lpInput.Size);