Code:
public class Input
{
private static InputWrapper KeyboardWrapper(ushort scanCode, bool keyUp)
{
InputWrapper wrapper = new InputWrapper();
wrapper.Type = SendInputType.Keyboard;
wrapper.MKH.Keyboard = new KeyboardInputData()
{
Key = 0,
Scan = scanCode,
Flags = (uint)KeyboardFlags.ScanCode,
Time = 0,
ExtraInfo = IntPtr.Zero
};
if (keyUp)
wrapper.MKH.Keyboard.Flags |= (uint)KeyboardFlags.KeyUp;
return wrapper;
}
public static void SimulateKeyPress(ushort scanCode, bool shift, bool ctrl, bool alt)
{
List<InputWrapper> inputs = new List<InputWrapper>();
// Add the key down and up
inputs.Add(KeyboardWrapper(scanCode, false));
inputs.Add(KeyboardWrapper(scanCode, true));
// For each of the modifier keys, put a key down before and key up after the key we're simulating
if (shift)
{
inputs.Insert(0, KeyboardWrapper((ushort)DirectXScanCode.DIK_LSHIFT, false));
inputs.Add(KeyboardWrapper((ushort)DirectXScanCode.DIK_LSHIFT, true));
}
if (ctrl)
{
inputs.Insert(0, KeyboardWrapper((ushort)DirectXScanCode.DIK_LCONTROL, false));
inputs.Add(KeyboardWrapper((ushort)DirectXScanCode.DIK_LCONTROL, true));
}
if (alt)
{
inputs.Insert(0, KeyboardWrapper((ushort)DirectXScanCode.DIK_LMENU, false));
inputs.Add(KeyboardWrapper((ushort)DirectXScanCode.DIK_LMENU, true));
}
// Send the list of inputs to the foreground application
SendInput((uint)inputs.Count, inputs.ToArray(), Marshal.SizeOf(typeof(InputWrapper)));
}
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint numberInputs, InputWrapper[] inputs, int sizeOfStructure);
[StructLayout(LayoutKind.Sequential)]
private struct InputWrapper
{
public SendInputType Type;
public MouseKeyboardHardwareUnion MKH;
}
private enum SendInputType : int
{
Mouse = 0,
Keyboard,
Hardware
}
[StructLayout(LayoutKind.Explicit)]
private struct MouseKeyboardHardwareUnion
{
[FieldOffset(0)]
public MouseInputData Mouse;
[FieldOffset(0)]
public KeyboardInputData Keyboard;
[FieldOffset(0)]
public HardwareInputData Hardware;
}
[StructLayout(LayoutKind.Sequential)]
private struct MouseInputData
{
public int X;
public int Y;
public uint MouseData;
public MouseEventFlags Flags;
public uint Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct KeyboardInputData
{
public ushort Key;
public ushort Scan;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct HardwareInputData
{
public int Msg;
public short ParamL;
public short ParamH;
}
[Flags]
enum MouseDataFlags : uint
{
XButton1 = 0x0001,
XButton2 = 0x0002
}
[Flags]
enum KeyboardFlags : uint
{
ExtendedKey = 0x1,
KeyUp = 0x2,
Unicode = 0x4,
ScanCode = 0x8
}
[Flags]
enum MouseEventFlags : uint
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x0040,
XDown = 0x0080,
XUp = 0x0100,
Wheel = 0x0800,
VirtualDesktop = 0x4000,
Absolute = 0x8000
}
public enum DirectXScanCode : ushort
{
DIK_ESCAPE = 0x01,
DIK_1 = 0x02,
DIK_2 = 0x03,
DIK_3 = 0x04,
DIK_4 = 0x05,
DIK_5 = 0x06,
DIK_6 = 0x07,
DIK_7 = 0x08,
DIK_8 = 0x09,
DIK_9 = 0x0A,
DIK_0 = 0x0B,
DIK_MINUS = 0x0C, /* - on main keyboard */
DIK_EQUALS = 0x0D,
DIK_BACK = 0x0E, /* backspace */
DIK_TAB = 0x0F,
DIK_Q = 0x10,
DIK_W = 0x11,
DIK_E = 0x12,
DIK_R = 0x13,
DIK_T = 0x14,
DIK_Y = 0x15,
DIK_U = 0x16,
DIK_I = 0x17,
DIK_O = 0x18,
DIK_P = 0x19,
DIK_LBRACKET = 0x1A,
DIK_RBRACKET = 0x1B,
DIK_RETURN = 0x1C, /* Enter on main keyboard */
DIK_LCONTROL = 0x1D,
DIK_A = 0x1E,
DIK_S = 0x1F,
DIK_D = 0x20,
DIK_F = 0x21,
DIK_G = 0x22,
DIK_H = 0x23,
DIK_J = 0x24,
DIK_K = 0x25,
DIK_L = 0x26,
DIK_SEMICOLON = 0x27,
DIK_APOSTROPHE = 0x28,
DIK_GRAVE = 0x29, /* accent grave */
DIK_LSHIFT = 0x2A,
DIK_BACKSLASH = 0x2B,
DIK_Z = 0x2C,
DIK_X = 0x2D,
DIK_C = 0x2E,
DIK_V = 0x2F,
DIK_B = 0x30,
DIK_N = 0x31,
DIK_M = 0x32,
DIK_COMMA = 0x33,
DIK_PERIOD = 0x34, /* . on main keyboard */
DIK_SLASH = 0x35, /* / on main keyboard */
DIK_RSHIFT = 0x36,
DIK_MULTIPLY = 0x37, /* * on numeric keypad */
DIK_LMENU = 0x38, /* left Alt */
DIK_SPACE = 0x39,
DIK_CAPITAL = 0x3A,
DIK_F1 = 0x3B,
DIK_F2 = 0x3C,
DIK_F3 = 0x3D,
DIK_F4 = 0x3E,
DIK_F5 = 0x3F,
DIK_F6 = 0x40,
DIK_F7 = 0x41,
DIK_F8 = 0x42,
DIK_F9 = 0x43,
DIK_F10 = 0x44,
DIK_NUMLOCK = 0x45,
DIK_SCROLL = 0x46, /* Scroll Lock */
DIK_NUMPAD7 = 0x47,
DIK_NUMPAD8 = 0x48,
DIK_NUMPAD9 = 0x49,
DIK_SUBTRACT = 0x4A, /* - on numeric keypad */
DIK_NUMPAD4 = 0x4B,
DIK_NUMPAD5 = 0x4C,
DIK_NUMPAD6 = 0x4D,
DIK_ADD = 0x4E, /* + on numeric keypad */
DIK_NUMPAD1 = 0x4F,
DIK_NUMPAD2 = 0x50,
DIK_NUMPAD3 = 0x51,
DIK_NUMPAD0 = 0x52,
DIK_DECIMAL = 0x53, /* . on numeric keypad */
DIK_F11 = 0x57,
DIK_F12 = 0x58,
}
}
class Program
{
static void Main(string[] args)
{
// You have 5 seconds to switch the application on which you'd like to receive the
// event to the foreground
Thread.Sleep(5000);
Input.SimulateKeyPress((ushort)Input.DirectXScanCode.DIK_3, false, false, false);
}
}
This code