How do you get AutoHotKey hotkeys to work with Remote Desktop in fullscreen on Windows 7?
6 Answers
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
-
2However, 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 send8
...:(
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 send8
in Windows.SendInput, {shift down}8{shift up}
works the other way around. Commented Nov 16, 2012 at 17:14
You also need to set "Apply windows key combinations" on the "Local resources" tab of remote desktop connection 'mstsc.exe' to "ON THIS COMPUTER"
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
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
}
}
}
}
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
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
}