最近购入了台17年12寸的 macbook,想着体验一下mac生态,但是熟悉之后感觉确实不错。尤其是 Command 键的位置和用法,但是切换回 Windows 的时候就不太顺畅了。于是就想写一个脚本,实现键位映射。但是用mac RDP win的时候发现这些映射又容易出问题,于是想办法搞成动态映射来解决这个问题。
本文介绍如何使用 AutoHotkey (v2.0) 编写脚本,实现动态键位映射 :既能在本地完美复刻 Mac 体验,又能智能识别远程桌面来源,自动适配 RDP 客户端的键位逻辑。
💡 核心痛点:本地与远程的“精神分裂”
在 Windows 上复刻 Mac 键位,最直接的思路是将键盘左下角的 Alt 映射为 Ctrl(因为 Mac 的 Command 键就在这个位置)。
然而,当你从一台 Mac 通过 Microsoft Remote Desktop 远程连接到这台 Windows 时,问题就出现了: 1. 本地使用时 :我们需要 Alt -> Ctrl。 2. Mac 远程连接时 :Mac 的 RDP 客户端通常会将 Command 键映射为 Windows 的 Win 键。此时,我们在 Mac 上按 Cmd + C,Windows 接收到的是 Win + C。
如果我们简单粗暴地全局重映射,就会导致远程连接时快捷键失效。我们需要一个“智能”的脚本,它能知道当前是谁在操作电脑 。
🔍 解决方案:WTSAPI 动态识别
Windows 提供了 WTSAPI (Windows Terminal Services API),允许我们查询当前会话的信息。通过 WTSQuerySessionInformation 函数,我们可以获取连接到当前会话的客户端名称(Client Name)。
本地登录 :客户端名称通常为空。
远程登录 :客户端名称会显示发起连接的设备名)。
利用这一点,我们可以编写一个 IsRemoteMac() 函数来动态判断当前的上下文。
🛠️ 脚本实现
以下是完整的 AutoHotkey v2 脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 #Requires AutoHotkey v2.0 #SingleInstance Force IsRemoteMac() { clientName := Trim(GetRdpClientName()) if (clientName = "" ) return false if InStr(clientName, "zihao-macbook" ) { return true } return false } GetRdpClientName() { try { pBuffer := 0 bytes := 0 if !DllCall("wtsapi32\WTSQuerySessionInformationW" , "Ptr" , 0 , "Int" , -1 , "Int" , 10 , "Ptr*" , &pBuffer , "UInt*" , &bytes) return "" name := StrGet(pBuffer, "UTF-16" ) DllCall("wtsapi32\WTSFreeMemory" , "Ptr" , pBuffer) return name } catch { return "" } } #HotIf IsRemoteMac() $!Tab:: { SendInput "{LAlt up}" Sleep 10 SendEvent "#{Tab}" return } $#/:: Send "^/" $#b:: Send "^b" $#s:: Send "^s" $#-:: Send "^-" $#=:: Send "^=" $#p:: Send "^p" $#[:: Send "^[" $#t:: Send "^t" $#+k:: Send "^+k" #HotIf #HotIf !IsRemoteMac() $!c:: Send "^c" $!v:: Send "^v" $!x:: Send "^x" $!z:: Send "^z" $!+z:: Send "^y" $!a:: Send "^a" $!s:: Send "^s" $!n:: Send "^n" $!w:: Send "^w" $!p:: Send "^p" $!,:: Send "^," $!b:: Send "^b" $!f:: Send "^f" $!h:: Send "^h" $!/:: Send "^/" $![:: Send "^[" $!+k:: Send "^+k" $!t:: Send "^t" $!r:: Send "^r" $!=:: Send "^{=}" $!-:: Send "^{-}" $!0:: Send "^0" #HotIf #HotIf !IsRemoteMac() && WinActive("ahk_exe Typora.exe") { $!1:: Send "^1" $!2:: Send "^2" $!3:: Send "^3" $!4:: Send "^4" $!5:: Send "^5" } #HotIf #HotIf !IsRemoteMac() && (WinActive("ahk_exe chrome.exe") || WinActive("ahk_exe msedge.exe") || WinActive("ahk_exe firefox.exe")) { $!Left:: Send "!{Left}" $!Right:: Send "!{Right}" } #HotIf #HotIf !IsRemoteMac() && WinActive("ahk_exe Code.exe") { $!+p:: Send "^+p" $!g:: Send "^g" } #HotIf #HotIf !IsRemoteMac() $!Left:: Send "{Home}" $!Right:: Send "{End}" $!Up:: Send "^{Home}" $!Down:: Send "^{End}" $!+Left:: Send "+{Home}" $!+Right:: Send "+{End}" $!+Up:: Send "^+{Home}" $!+Down:: Send "^+{End}" $!e:: Send "#e" ~!Space:: { KeyWait "Alt" Sleep 50 Send "#s" return } $#z:: Send "!z" $#1:: Send "^!1" $#2:: Send "^!2" $#3:: Send "^!3" ~LAlt:: Send "{Blind}{vkE8}" ~LAlt Up:: { if (A_PriorKey = "LAlt" ) { Send "{LWin}" } } #HotIf
🚀 如何使用
安装 AutoHotkey v2 。
创建一个新文件 MacKeys.ahk,将上述代码粘贴进去。
双击运行即可。
(可选)将其放入 Windows 的启动文件夹,实现开机自启。
仓库地址 放到这里,希望这对你有帮助!