24

I have an application which injects keystrokes into applications via SendKeys.

Unfortunately, the application will not work when I am running it via Remote Desktop because of the well known issue that SendKeys doesn't work with Remote Desktop.

Has anyone solved this issue before, or have any good suggestions on how to resolve it?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Cameron
  • 2,903
  • 1
  • 30
  • 31

4 Answers4

9

SendKeys is not a good fit mainly due to:

  • It can only send keys to active/focused application, which is never guaranteed to work because the the active application can change between the time the keys are actually sent.
  • RDP and many other libraries (e.g., DirectX) block them mainly for security reasons.

Better alternatives:

Sample code using SendMessage:

HWND hwndNotepad = FindWindow(_T("Notepad"), NULL);
HWND hwndEdit = FindWindowEx(hwndNotepad, NULL, _T("Edit"), NULL);
SendMessage(hwndEdit, WM_SETTEXT, NULL, (LPARAM)_T("hello"));
Community
  • 1
  • 1
Mrchief
  • 75,126
  • 20
  • 142
  • 189
  • 3
    For RDP sessions with added security options your only two ways to simulate user input is either writing a driver (https://msdn.microsoft.com/en-us/library/windows/hardware/hh439659%28v=vs.85%29.aspx) which is a hassle to C# developers or using SendInput which does work perferctly! I recommend using the library http://inputsimulator.codeplex.com/ But watch out to use InputSimulator.SimulateTextEntry("text"); instead of InputSimulator.SimulateKeyDown(VirtualKeyCode.VK_B); – McK Oct 14 '15 at 06:34
5

In my case I was successfully using WinAPI's SendInput with hardware scan codes. It seems like SendKeys maps chars to scan codes incorrectly.

Vasily Nosov
  • 51
  • 1
  • 2
  • 2
    +1 This is the shortest and correct answer if using RDP with enhanced security (disabled keyboard, etc.). I recommend this library: http://inputsimulator.codeplex.com/ But watch out to use InputSimulator.SimulateTextEntry("text"); instead of InputSimulator.SimulateKeyDown(VirtualKeyCode.VK_B); – McK Oct 14 '15 at 06:36
3

You can workaround RDP issue by having desktop always logged in before use (or configured for auto-login @ every boot).

And even with the auto-login, if you ever need remote desktop access to run automation, or manage system, etc., the preferred method is using VNC for remote access rather than RDP. Reason is VNC is cross platform and you won't run into this RDP issue. VNC works like a relay of your actual desktop (RDP console session 0 or the "head" of the machine), the disadvantage being one remote session at a time only (or you all share the same desktop + keyboard + mouse). VNC will work for virtual machines too. Use VNC instead of RDP or local (RDP) access from the (VMWare/Hyper-V/Xen) virtual machine manager software.

The only thing to watch out for with VNC still is that the desktop not be configured to auto-lock on idle or screensaver, that may also stop send keys and GUI automation from running, so be sure to disable that. Screensaver & monitor power save is ok, just no auto-lock & password protect.

NOTE: I'm not sure, but believe since VNC relays the desktop "as is", it is the same as executing locally from the app/system's point of view, so it should in theory also be able to fool the system/app that doesn't allow SendKeys via RDP. I've had no issues using this VNC method for AutoIt + SendKeys, whether I was actively connected via VNC, or disconnected (sendkeys/automation still continues to work after disconnect because on the actual desktop, it's still logged in, just that VNC not active).

David
  • 3,223
  • 3
  • 29
  • 41
  • Intersting, thanks for the info. Is there any particular VNC software you recommend? Preferably open source. – Frank Schwieterman Sep 07 '11 at 17:42
  • Sorry, can't recommend much beyond Windows, I've only used VNC server and clients on Windows. On Windows, RealVNC and TightVNC work nicely, don't recall if is OSS, but they have free and commercial versions. I only use free. The only limitation of the free ones is often about encryption security levels. But that's often not so much a concern if you work within VPN or corporate network. – David Sep 07 '11 at 19:02
0

In my case I was using sendkeys as part of test automation. It would not work from my build machine, where the build agent runs through remote desktop protocol. I'm not happy about it but I was able to skip that test as part of my automated builds.

Using Win32 calls to send window messages might work, if I have time I may try that someday.

Anyhow, here is the check to see if the current code is running in a remote desktop session:

System.Environment.GetEnvironmentVariable("SESSIONNAME").StartsWith("RDP-")
Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130