#c# #key #code-injection
#c# #Клавиша #внедрение кода
Вопрос:
Я пытаюсь ввести ключи в программу. Мне удалось ввести ключи, но я не могу найти код виртуального ключа для знака @. Я нашел этот сайт, который был очень полезен, но все еще не могу его найти. Ключи.Отправить (); не вариант, поскольку я не хочу, чтобы окно было выбрано, я хочу иметь возможность делать все это в фоновом режиме.
Пока это мой код:
const UInt32 WM_KEYDOWN = 0x0100;
int VK_A = 0x41;
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcessesByName("Notepad");
foreach (Process proc in processes)
{
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_A, 0);
}
}
Это приведет к отправке ключа A в блокнот.
Буду признателен за любую помощь.
Комментарии:
1. Заставил его работать, используя: postMessage(proc.MainWindowHandle, WM_CHAR, (int) ‘@’, 0);
Ответ №1:
Windows определяет специальные константы для каждой клавиши, которую пользователь может нажать, называемые кодами виртуальных клавиш. На вашей клавиатуре нет клавиши @, вместо этого вы используете Shift 2 (по крайней мере, на моей клавиатуре), чтобы сделать это.
Я думаю, что вы не можете имитировать Shift 2 с помощью postMessage.
Смотрите http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx .
Ответ №2:
@
сам по себе не имеет соответствующего ключа. Вы можете отправить ключ (ы) соответствующее ему состояние клавиши-модификатора, которое на американских клавиатурах равно Shift 2.
Но на других раскладках клавиатуры клавиши другие. Например, в немецкой раскладке это AltGr Q.
Или вы можете отправить WM_CHAR напрямую. Это будет работать с большинством приложений, однако некоторые (обычно игры) его не принимают.
Сначала я бы попробовал WM_CHAR
, и только если это не сработает, переключитесь на WM_KEYDOWN.
Комментарии:
1. это действительно сработает? blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx
2. вы это тестировали? Отправка WM_KEYDOWN с кодом виртуальной клавиши для shift фактически не изменяет состояние клавиатуры, происходит обратное: WM_KEYDOWN генерируется в ответ на изменение состояния клавиатуры. Таким образом, отправка
shift-down, 2 down, 2 up, shift up
, скорее всего, не сработает.3. Прошло много времени с тех пор, как я делал подобные вещи, поэтому я, возможно, допустил какую-то ошибку и перепутал ее с методами отправки более низкого уровня.
4. Похоже, я смешал технику для WM_KEYDOWN с техникой для
keybd_event
.
Ответ №3:
@
не является ключом сам по себе и является «альтернативным» символом, что означает, что он может быть применен только при нажатии клавиши-модификатора (shift); поэтому вам может потребоваться объединить два значения:
const int VK_OEM7 = 0xDE; // (" ') - this can be 'any' key, apparently
const int VK_SHIFT = 0xA0; // (left shift)
var keycode = VK_OEM7 | VK_SHIFT;
Другая возможность заключается в том, что вам может потребоваться нажимать каждую клавишу в последовательности вызовов.
В любом случае, вам нужно больше, чем один ключевой код.
Хотя я уверен, что вам придется воспользоваться вторым подходом, о котором я упоминал выше (объединение значений вряд ли сработает), я стал немного обеспокоен тем, как вам на самом деле удалось разместить символы в notepad
в первую очередь, учитывая, что вы используете MainWindowHandle
вместо дескриптора редактора — на всякий случай, если вы столкнетесь с какими-либо еще не замеченными проблемами, следующий код захватывает текстовую область notepad и позволяет вам «размещать» в ней:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
var editorHandle = FindWindowEx(proc.MainWindowHandle, new IntPtr(0), "Edit", null);
Ответ №4:
Вот альтернативное решение — найдите, какая клавиатура используется во внешнем приложении, и сопоставьте символ с соответствующей клавишей, если таковая имеется.
C / C У меня нет удобных определений C #
HWND handle; // the handle of the window you wish to type to
DWORD idThread = GetWindowThreadProcessId(handle, NULL);
// may also want to work in the same input queue - allows forground and focus to work
// AttachThreadInput(GetCurrentThreadId(), idThread,TRUE);
HKL hklRemote = GetKeyboardLayout(idThread);
SHORT VkCode = VkKeyScanEx(key, hklRemote );
Кроме того, если вы хотите отправить несколько клавиш (или щелчков мыши) без прерывания пользователем, то SendInput может быть лучшим вариантом.