The Windows API has SendInput, and you need to send the hardware scan code of the key you wish to press for games to detect it (I know this from experience).
I have a small example in C++ here, I'm assuming you can Pinvoke it with no trouble.
#include "stdafx.h"
#pragma comment(lib,"user32")
using namespace std;
int main()
{
char ch = 'a';
INPUT key;
memset(&key,0,sizeof(INPUT));//Zero the structure.
key.type = INPUT_KEYBOARD;
key.ki.dwExtraInfo = GetMessageExtraInfo();//<-- you will need to pinvoke this too.
key.ki.wScan =
static_cast<WORD>(MapVirtualKeyEx(VkKeyScanA(ch), MAPVK_VK_TO_VSC, GetKeyboardLayout(0)));//more pinvoking
key.ki.dwFlags = KEYEVENTF_SCANCODE;//<-- you will probably have to declare this constant somewhere-
//in your C# program.
//Ready to send the key-down event.
SendInput(1, &key, sizeof(INPUT));
Sleep(1000);//Wait one second before sending key-up.
//Sending key-up.
key.ki.dwExtraInfo = GetMessageExtraInfo();
key.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;//Key-up need be defined too, or just use the value.
SendInput(1, &key, sizeof(INPUT));
}
http://www.pinvoke.net/default.aspx/user32/sendinput.html
http://msdn.microsoft.com/en-us/library/ms646310(v=vs.85).aspx
Overall it seems very tedious to use the raw Winapi w/ C# to do this, there may be a better way that I am not aware of.
It appears as though SendKeys offers the familiar C# level of abstraction, please see here: http://msdn.microsoft.com/en-us/library/ms171548.aspx
--edit--
Actually it sounds as if a windows low-level keyboard hook would be better for your purpose, you can intercept the input before it reaches the application and either prevent it from reaching it or modify it whilst simulating input in response.
There appears to be a C# wrapper hosted on CodeProject for creating Low-level hooks.
http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx