10

How do you get AutoHotKey hotkeys to work with Remote Desktop in fullscreen on Windows 7?

6 Answers 6

8

As user16659 notes, Reload makes the hotkeys work again (But his script did not work for me).

Basically, I now have two scripts running, one which contains my hotkeys and hotstrings "script.ahk" and another which will reload this script if RDP is maximised "controller.ahk".

script.ahk:

#SingleInstance force
::hw::Hello World

controller.ahk:

Run "autohotkey" "script.ahk"

#Persistent
SetTimer, ReloadOnRDPMaximized, 500
return

ReloadOnRDPMaximized:
If WinActive("ahk_class TscShellContainerClass")
{
    WinGet, maxOrMin, MinMax, ahk_class TscShellContainerClass

    if (maxOrMin = 0) {
        WinGetPos, PosX, PosY, WinWidth, WinHeight, ahk_class TscShellContainerClass

        if (PosY = 0) {
            ; it is fully maximized therefore reload "script.ahk"
            Run "autohotkey" "script.ahk"

            ; wait until window gets deactivated so you don't reload it again.
            WinWaitNotActive, ahk_class TscShellContainerClass

        }
    }
}
return
2
  • 2
    However, I have noticed that even my solution does not work because in RDP it does not send the shift key press for hot strings, e.g. if you send * then it will send 8... :( Commented Nov 16, 2012 at 15:23
  • I had to do something like SendInput, {shift}8{shift up} to send * in RDP, but it will send 8 in Windows. SendInput, {shift down}8{shift up} works the other way around.
    – user16659
    Commented Nov 16, 2012 at 17:14
11

You also need to set "Apply windows key combinations" on the "Local resources" tab of remote desktop connection 'mstsc.exe' to "ON THIS COMPUTER"MSTSC WINDOWS KEY COMBINATIONS

1

To make AHK work with Microsoft's Terminal Server client in fullscreen, AHK has to reload after the Remote Desktop window is activated.

SetTimer, waitforrdp, -250
return

:*:ppp::password
:*:ccc::
SendInput, {shift}C{shift up}
SendInput, apitalized
return

waitforrdp:
IfWinActive, ahk_class TscShellContainerClass
{
    WinWaitNotActive, ahk_class TscShellContainerClass,,3600
}
WinWaitActive, ahk_class TscShellContainerClass,,3600
Reload
return
1

The code of user yakrider didn't work for me, but based on https://github.com/CaptainHelm/AHK-RDP-Scripts/blob/main/Primary I use this code which suspends hotkeys while RDP is not active and activates them (with a short delay) when RDP gets active, which makes the hotkeys work in the full-screen RDP session:

debug_audio := true  ; Use audio beeps on suspend on/off to help debugging

#persistent
setTimer, windowWatch, 500  ; Run windowWatch() every 500ms
return

windowWatch()
{
  global debug_audio
  static active := true  ; Ensure that we suspend hotkeys upon script (re-)start
  if WinActive("ahk_class TscShellContainerClass") {
    if (!active) {
      active := true
      ; Short sleep to make sure the remote desktop keyboard hook is active
      Sleep 100
      ; Coming out of suspend mode recreates the keyboard hook, giving
      ; our hook priority over the remote desktop client's.
      suspend off
      if (debug_audio) {
        SoundBeep
      }
    }
  } else {
    if (active) {
      active := false
      suspend on
      if (debug_audio) {
        SoundBeep 300
      }
    }
  }
}

0

Can't add comment to top answer, but I have modified the suggested script that Tahir linked to his blog in the top answer to make it cleaner and easier to use.

The following works by suspending the local script when full screen RDP is active instead of trying to kill and restart the separate script version everytime focus is moved. This is lighter, and also avoids littering the notification tray with lots of zombie AHK icons for the killed scripts. This also means you can just add this to your existing script instead of having to run both of them separately!

; this line should be put on top (auto-exec) section of ahk script
SetTimer, SuspendOnRDPMaximized, 500

; this actual code label and the fn can be put anywhere in the script file
SuspendOnRDPMaximized:
If WinActive("ahk_class TscShellContainerClass") {
    WinGet, maxOrMin, MinMax, ahk_class TscShellContainerClass
    if (maxOrMin = 0) {
        WinGetPos, PosX, PosY, WinWidth, WinHeight, ahk_class TscShellContainerClass
        if (PosY = 0) {  ; it is fully maximized
            Suspend, On
            WinWaitNotActive, ahk_class TscShellContainerClass
            Suspend, Off
        }
    }
}
return
0

For those that don't like timer based solutions: utilize that there's an artificial vkFF keystroke that is sent when the RDP client becomes active (don't ask me why/how/what it means). I react to this keystroke to reload the keyboard hook, while allowing ctrl/alt to be pressed simultaneously as the vkFF keystroke as I might have them pressed at the same time.

; To get a way to maximimize remote desktops on keyboards without a break key
; Press ctrl+alt+insert to send ctrl+alt+break
^!Insert::Send("!^{CtrlBreak}")


; Try to fix that above hotkey works even when the RDP Session has taken control of the keyboard
; Allow ctrl & alt combinations since one of the keys might still be in "Down" state when the VKFF key arrives.
GroupAdd "TSClientGroup", "ahk_class TscShellContainerClass"
#HotIf WinActive("ahk_group TSClientGroup")
~VKFF::
~^VKFF::
~!VKFF::
~^!VKFF::
{
; An artificial vkFF keystroke is detected when the RDP client becomes active.
; At that point, the RDP client installs its own keyboard hook which takes
; precedence over ours, so ...
if (A_TimeIdlePhysical > A_TimeSinceThisHotkey)
{
    Suspend True
    Suspend False  ; ... reinstall our hook.
    Sleep 50
}
return
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .