С# Имитация нажатия клавиатуры в ОС ниже Windows 8

Я использую следующий код на С# для имитации нажатия на клавиатуру:

[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);
    }
}

Я протестировал его на Windows Xp, 7, 8.1, 10 и Server 2012. В Windows 7 и Xp внешнее окно приложения обрабатывается правильно, однако ключи не отправляются. На системах выше Win 7 все правильно. Как мне это исправить?

Редактировать: я проверил это на .NET 4.0 Client Profile и .NET 4.6.1 на 32- и 64-битных машинах, но результаты такие же, как описано выше.


person user3601171    schedule 31.10.2016    source источник
comment
Вы можете попробовать keybd_event вместо SendKeys.   -  person sknt    schedule 31.10.2016


Ответы (2)


Я думаю, вы можете пойти с этим грубым кодом

    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);
    }

Использовать

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

отправить "Enter".

Обратите внимание, что вы можете использовать SendMessage вместо PostMessage. Разница в том, что последний не ждет обработки ключа. У них одинаковая подпись:

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

Вам не нужно звонить SetForegroundWindow(process.MainWindowHandle);, если вы просто хотите отправить ключи.

person Sergey L    schedule 31.10.2016

Спасибо за ваш ответ. Я попытался использовать PostMessage для отправки Ctrl+F10 в другое окно. Вот мой код:

public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int VK_CONTROL = 0x11;
public const int VK_F10 = 0x79;

PostMessage(process.MainWindowHandle, WM_KEYDOWN, VK_CONTROL, null);
PostMessage(process.MainWindowHandle, WM_KEYDOWN, VK_F10, null);
PostMessage(process.MainWindowHandle, WM_KEYUP, VK_F10, null);
PostMessage(process.MainWindowHandle, WM_KEYUP, VK_CONTROL, null);

Однако он не передает ключи приложению.

person user3601171    schedule 03.11.2016