8

I'm using WPF and I imported the System.Windows.Form reference. Here's my code:

Process[] process = Process.GetProcessesByName("wmplayer");
SetForegroundWindow(process[0].MainWindowHandle);
Thread.Sleep(200);
System.Windows.Forms.SendKeys.Send("^p");

The Windows Media Player do Focus, but no keystroke is Received. Why?

svick
  • 236,525
  • 50
  • 385
  • 514
Ziad Akiki
  • 2,601
  • 2
  • 26
  • 41
  • 1
    It appears System.Windows.Forms.SendKeys.Send sends keystrokes to the "active" application (http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx). I'm not entirely sure on what that means, but it might be limited to the process it is executing in. Try using the Win32 api, check out this question http://stackoverflow.com/questions/3047375/simulating-key-press-c-sharp – James Jul 09 '12 at 20:55
  • 3
    @James it is definitely not limited to the process it is executing in. – Tim Jul 09 '12 at 21:21

2 Answers2

12

You can use WinAPI instead of SendKeys:

[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
public static void PressKey(Keys key, bool up) {
    const int KEYEVENTF_EXTENDEDKEY = 0x1;
    const int KEYEVENTF_KEYUP = 0x2;
    if (up) {
        keybd_event((byte) key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr) 0);
    }
    else {
        keybd_event((byte) key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr) 0);
    }
}

void TestProc() {
    PressKey(Keys.ControlKey, false);
    PressKey(Keys.P, false);
    PressKey(Keys.P, true);
    PressKey(Keys.ControlKey, true);
}
Alex Butenko
  • 3,664
  • 3
  • 35
  • 54
  • Per the docs (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646304(v=vs.85).aspx), keybd_event has been superseded and SendInput should be used instead. – Tim Jul 09 '12 at 21:23
  • It's true, but this code works fine on all versions of Windows from XP to Windows 8 (Maybe the other too, but I have not tested). And in my opinion, to use SendInput is not as easy as keybd_event. – Alex Butenko Jul 09 '12 at 21:48
  • Exactly what I needed. Thanks now I can access MediaPlayPause button and so On... – Ziad Akiki Jul 10 '12 at 05:59
  • 1
    keybd_event has been kept for compatibility reasons. – string.Empty Sep 04 '13 at 14:01
  • Anyone knows why sequence Keys.LWin, false + Keys.Shift , false + Keys.Left, false and than reverse sequence with true won't send window to other monitor, but it causes behavior like LWin was pressed separately, and then Shift + Left. – watbywbarif Feb 14 '14 at 09:50
3

In WPF applications you have to use SendKeys.SendWait() (English Documentation) instead.

Just doublechecked it, while Send() is working for WinForms application, WPF throws an InvalidOperationException although both target .net 4.0.

Check above link for more information.

Mark Hall
  • 53,938
  • 9
  • 94
  • 111
nik
  • 1,471
  • 1
  • 12
  • 16