user3601171 user3601171 - 1 month ago 11
C# Question

C# Simulating keyboard press on OS below Windows 8

I am using the following code in C# to simulate the keyboard pressing:

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

[DllImport("user32")]
private static extern bool SetForegroundWindow(IntPtr hwnd);

void sim_key(string text, string proc)
{
var process = Process.GetProcessesByName(proc).FirstOrDefault();
if (process != null && process.MainWindowHandle != IntPtr.Zero)
{
SetForegroundWindow(process.MainWindowHandle);
SendKeys.Send(kat_id);
}
}


I tested it on Windows Xp, 7, 8.1, 10, and Server 2012. On windows 7 and Xp, the external app window is handled properly, however the keys are not being sent. On systems above Win 7 everything is correct. How should I fix it?

Edit:
I checked it on .NET 4.0 Client Profile and .NET 4.6.1 on 32 and 64 bit machines, but results are the same as described above.

Answer

I think you can go with this rough code

    const int WM_CHAR = 0x0102;
    const int WM_KEYDOWN = 0x0100;

if (process != null && process.MainWindowHandle != IntPtr.Zero)
    {
      PostMessage(process.MainWindowHandle, WM_CHAR, (int) <a character you want to send> , 1);
    }

Use

PostMessage(process.MainWindowHandle, WM_KEYDOWN, 13, 1);

to send the "Enter".

Note that you can use SendMessage instead of PostMessage. The difference is the last one does not wait the processing of the key. They have the same signature:

[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

You don't need calling SetForegroundWindow(process.MainWindowHandle); if you just want to send keys.