heroicis23
heroicis23

Reputation: 21

Powershell simulate Keyboard

I have a problem using sendkeys is Powershell. I'm trying to make a script that wil send the keys: shift,w,a,s,d to a game. The code i'm trying is:

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

But when I use this it just sends "Wasd". It won't change the movement, i can see that this has been send in the in-game console.

Is there a way i can simulate the keypresses?

It can by done for the left mouse button using this:

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

Is there something similar for the keyboard?

Upvotes: 2

Views: 15843

Answers (2)

FoxDeploy
FoxDeploy

Reputation: 13537

The sendKeys method doesn't seem to support more than one character at a time, so you need to automate sending many keys to the sendkeys method.

After some thought, here's what I came up with.

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

Here's the result:

Send keys with PowerShell, awesome![1]

Now, for a line-by-line of what's happening:

  • Adding the type, as you did before.
  • Next, a three second timeout message, in which I quickly double-clicked and opened Notepad.
  • Finally, I'm making a String with the characters 'WASD', then calling the system string .ToCharArray() method, which converts a string into an array of characters. Now I'm working with W,A,S,D, instead of WASD.

For each of those objects (each letter, W,A,S, and D) I'm calling the SendWait() static method. Within a ForEach script block, the $_ symbol is used to refer to the current object.

This the most succinct and easy to understand method I could come up with.

Upvotes: 3

sodawillow
sodawillow

Reputation: 13176

Try this:

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

I got wasd as a result so I guess it worked.

Upvotes: 1

Related Questions