Send keys through SendInput in user32.dll
You aren't setting the flags and scan fields, depending on the keystrokes desired, you will need to set these correctly to get the OS to recognize the keys correctly.
You might consider using the Input Simulator library, since it already does what you want and you don't have to recreate the wheel. Just make sure to look through the forums as there are some good patches in there that need to be set, since the author abandoned the project in 2009. It's a good library nonetheless.
Another way of sending keyboard input to a window (I use this for UI testing) is to use the Unicode alternative in KEYBDINPUT which saves you from mapping each character to the virtual key:
public static void SendString(string inputStr)
{
var hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
WinAPI.SetForegroundWindow(hWnd);
List<WinAPI.INPUT> keyList = new List<WinAPI.INPUT>();
foreach (short c in inputStr)
{
switch (c)
{
case 8: // Translate \t to VK_TAB
{
WinAPI.INPUT keyDown = new WinAPI.INPUT();
keyDown.type = 1; //Keyboard
keyDown.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_TAB;
keyDown.union.keyboardInput.dwFlags = 0;
keyDown.union.keyboardInput.wScan = 0; //use VirtualKey
keyList.Add(keyDown);
WinAPI.INPUT keyUp = new WinAPI.INPUT();
keyUp.type = 1; //Keyboard
keyUp.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_TAB;
keyUp.union.keyboardInput.dwFlags = 0x0002;
keyUp.union.keyboardInput.wScan = 0; //use VirtualKey
keyList.Add(keyUp);
}
break;
case 10: // Translate \n to VK_RETURN
{
WinAPI.INPUT keyDown = new WinAPI.INPUT();
keyDown.type = 1; //Keyboard
keyDown.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_RETURN;
keyDown.union.keyboardInput.dwFlags = 0;
keyDown.union.keyboardInput.wScan = 0; //use VirtualKey
keyList.Add(keyDown);
WinAPI.INPUT keyUp = new WinAPI.INPUT();
keyUp.type = 1; //Keyboard
keyUp.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_RETURN;
keyUp.union.keyboardInput.dwFlags = 0x0002;
keyUp.union.keyboardInput.wScan = 0; //use VirtualKey
keyList.Add(keyUp);
}
break;
default:
{
WinAPI.INPUT keyDown = new WinAPI.INPUT();
keyDown.type = 1; //Keyboard
keyDown.union.keyboardInput.wVk = 0; //Use unicode
keyDown.union.keyboardInput.dwFlags = 0x0004; //Unicode Key Down
keyDown.union.keyboardInput.wScan = c;
keyList.Add(keyDown);
WinAPI.INPUT keyUp = new WinAPI.INPUT();
keyUp.type = 1; //Keyboard
keyUp.union.keyboardInput.wVk = 0; //Use unicode
keyUp.union.keyboardInput.dwFlags = 0x0004 | 0x0002; //Unicode Key Up
keyUp.union.keyboardInput.wScan = c;
keyList.Add(keyUp);
}
break;
}
}
WinAPI.SendInput((uint)keyList.Count, keyList.ToArray(), Marshal.SizeOf(typeof(WinAPI.INPUT)));
}
You could try this. It works for : Shift + A, Ctrl + LShiftv + S, Ctrl + A
The others I didn't try but I think you could send any key combination
public static void MultiKeyPress(KeyCode[] keys){
INPUT[] inputs = new INPUT[keys.Count() * 2];
for(int a = 0; a < keys.Count(); ++a){
for(int b = 0; b < 2; ++b){
inputs[(b == 0) ? a : inputs.Count() - 1 - a].Type = 1;
inputs[(b == 0) ? a : inputs.Count() - 1 - a].Data.Keyboard = new KEYBDINPUT() {
Vk = (ushort)keys[a],
Scan = 0,
Flags = Convert.ToUInt32((b == 0)?0:2),
Time = 0,
ExtraInfo = IntPtr.Zero,
};
}
}
if (SendInput(Convert.ToUInt32(inputs.Count()), inputs, Marshal.SizeOf(typeof(INPUT))) == 0)
throw new Exception();
}
//call with this :
MultiKeyPress(new virtualInputs.KeyCode[] { KeyCode.LSHIFT, KeyCode.KEY_A });
/!\ the window that have the focus will get the keypress so you need to make sure the right window have the focus