Powershell имитировать клавиатуру

У меня проблема с использованием sendkeys - это Powershell. Я пытаюсь создать сценарий, который будет отправлять ключи: shift, w, a, s, d в игру. Код, который я пытаюсь сделать:

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait(+{w}{a}{s}{d});

Но когда я использую это, он просто отправляет «Wasd». Это не изменит движения, я вижу, что это было отправлено в игровой консоли.

Есть ли способ имитировать нажатия клавиш?

Это можно сделать для левой кнопки мыши, используя следующее:

    $signature=@' 
          [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
          public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
    '@ 

    $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru

$SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0);
$SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0);

Есть что-то подобное с клавиатурой?


person heroicis23    schedule 13.12.2015    source источник


Ответы (2)


Кажется, что метод sendKeys не поддерживает более одного символа за раз, поэтому вам нужно автоматизировать отправку множества ключей методу sendkeys.

Поразмыслив, я пришел к следующему.

Add-Type -AssemblyName System.Windows.Forms    
timeout 3
'WASD'.ToCharArray() | ForEach-Object {[System.Windows.Forms.SendKeys]::SendWait($_)}

Вот результат:

Отправляйте ключи с помощью PowerShell, здорово! [1]

А теперь построчно о том, что происходит:

  • Добавляем тип, как и раньше.
  • Затем сообщение о трехсекундном тайм-ауте, в котором я быстро дважды щелкнул и открыл Блокнот.
  • Наконец, я создаю строку с символами «WASD», а затем вызываю метод .ToCharArray() системной строки, который преобразует строку в массив символов. Теперь работаю с W, A, S, D вместо WASD.

Для каждого из этих объектов (каждой буквы W, A, S и D) я вызываю статический метод SendWait(). Внутри блока сценария ForEach символ $_ используется для ссылки на текущий объект.

Это самый лаконичный и простой для понимания метод, который я мог придумать.

person FoxDeploy    schedule 13.12.2015
comment
Хммм [System.Windows.Forms.SendKeys]::SendWait("{t}{y}{p}{e}{t}{h}{i}{s}{p}{l}{e}{a}{s}{e}") здесь работает - person sodawillow; 13.12.2015
comment
Спасибо @FoxDeply за ответ, единственная проблема в том, что это не решает мою проблему. Похоже, что игра не принимает метод SendWait. Мой плеер не перестает двигаться. Но когда я открываю что-то вроде окна чата, оно набирает WASD. Я думаю, что он должен быть больше похож на второй отправляемый мной код, чтобы игра приняла его как реальный ввод. - person heroicis23; 13.12.2015
comment
Тогда игра может иметь некоторую защиту от sendkeys. - person FoxDeploy; 13.12.2015
comment
@sodawillow, я почти уверен, что это противоречит рекомендациям по переполнению стека, чтобы проголосовать против других ответов на вопрос, на который вы ответили. - person FoxDeploy; 13.12.2015
comment
Я прокомментировал свой голос: я просто не согласен с самым первым утверждением ответа: Похоже, что метод sendKeys не поддерживает более одного символа одновременно. Если я нарушил здесь правило, извините. Но это явно не мое понимание правил голосования. Я сейчас прочитаю раздел помощи (здесь нет сарказма :)). Более того, я думал, что вопрос был больше нацелен на клавишу Shift, чем на что-либо еще, но я понимаю, что ошибся. - person sodawillow; 13.12.2015
comment
Одна мысль, sendWait специально ждет, пока другое приложение подтвердит нажатие клавиши. Что насчет попытки отправки или другого метода? - person FoxDeploy; 13.12.2015
comment
Отправить тоже не работает. Я подумал, что это может помочь: inputsimulator.codeplex.com, но это для C #, и я не Я не знаю, как использовать его в Powershell. - person heroicis23; 14.12.2015
comment
Думаю, это тоже может сработать: pinvoke.net/default.aspx/user32.SendInput, но только я не знаю, как использовать это в PowerShell - person heroicis23; 14.12.2015

Попробуй это:

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait("+")
[System.Windows.Forms.SendKeys]::SendWait("{w}{a}{s}{d}")

В результате я получил wasd, так что, думаю, это сработало.

person sodawillow    schedule 13.12.2015