KeyMapping:win上使用mac键位

最近购入了台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
#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 ; WTS_CURRENT_SERVER_HANDLE
, "Int", -1 ; WTS_CURRENT_SESSION
, "Int", 10 ; WTSClientName
, "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" ; 制表/新建标签页 (Win + T -> Ctrl + T)
$#+k::Send "^+k" ; 插入代码块 (Win + Shift + K -> Ctrl + Shift + K)


#HotIf

#HotIf !IsRemoteMac()
$!c::Send "^c" ; 复制 (Alt + C -> Ctrl + C) 实现 Cmd + C
$!v::Send "^v" ; 粘贴 (Alt + V -> Ctrl + V) 实现 Cmd + V
$!x::Send "^x" ; 剪切 (Alt + X -> Ctrl + X) 实现 Cmd + X
$!z::Send "^z" ; 撤销 (Alt + Z -> Ctrl + Z) 实现 Cmd + Z
$!+z::Send "^y" ; 重做 (Alt + Shift + Z -> Ctrl + Y) 实现 Cmd + Shift + Z
$!a::Send "^a" ; 全选 (Alt + A -> Ctrl + A) 实现 Cmd + A
$!s::Send "^s" ; 保存 (Alt + S -> Ctrl + S) 实现 Cmd + S
$!/::Send "^/" ; 注释 (Alt + / -> Ctrl + /) 实现 Cmd + /
$!p::Send "^p" ; 搜素 (Alt + P -> Ctrl + P) 实现 Cmd + P
$!w::Send "^w" ; 关闭 (Alt + W -> Ctrl + W) 实现 Cmd + W
$![::Send "^[" ; 反缩进 (Alt + [ -> Ctrl + [) 实现 Cmd + [
$#z::Send "!z" ; 自动换行 (Win + Z -> Alt + Z) 实现 Cmd + Z
;$!t::Send "^t" ; 制表/新建标签页 (Alt + T -> Ctrl + T)
$!+k::Send "^+k" ; 插入代码块 (Alt + Shift + K -> Ctrl + Shift + K)
$!,::Send "^," ; 菜单 (Alt + , -> Ctrl + ,)

$!b::Send "^b" ; 加粗 (Alt + B -> Ctrl + B) 实现 Cmd + B
$!n::Send "^n" ; 新建 (Alt + N -> Ctrl + N) 实现 Cmd + N
$!e::Send "#e" ; 打开资源管理器 (Alt + E -> Win + E) 实现 Cmd + E
$!f::Send "^f" ; 查找 (Alt + F -> Ctrl + F) 实现 Cmd + F
$!h::Send "^h" ; 替换 (Alt + H -> Ctrl + H) 实现 Cmd + H
$!t::Send "^t" ; 新建标签页 (Alt + T -> Ctrl + T) 实现 Cmd + T
$!r::Send "^r" ; 刷新 (Alt + R -> Ctrl + R) 实现 Cmd + R
$!=::Send "^{=}" ; 放大 (Alt + = -> Ctrl + =) 实现 Cmd + =
$!-::Send "^{-}" ; 缩小 (Alt + - -> Ctrl + -) 实现 Cmd + -
$!0::Send "^0" ; 恢复大小 (Alt + 0 -> Ctrl + 0) 实现 Cmd + 0

$!Left::Send "{Home}" ; 光标移至行首 (Alt + Left -> Home) 实现 Cmd + Left
$!Right::Send "{End}" ; 光标移至行尾 (Alt + Right -> End) 实现 Cmd + Right
$!Up::Send "^{Home}" ; 光标移至文档头 (Alt + Up -> Ctrl + Home) 实现 Cmd + Up
$!Down::Send "^{End}" ; 光标移至文档尾 (Alt + Down -> Ctrl + End) 实现 Cmd + Down
$!+Left::Send "+{Home}" ; 选中至行首 (Alt + Shift + Left -> Shift + Home) 实现 Cmd + Shift + Left
$!+Right::Send "+{End}" ; 选中至行尾 (Alt + Shift + Right -> Shift + End) 实现 Cmd + Shift + Right
$!+Up::Send "^+{Home}" ; 选中至文档头 (Alt + Shift + Up -> Ctrl + Shift + Home) 实现 Cmd + Shift + Up
$!+Down::Send "^+{End}" ; 选中至文档尾 (Alt + Shift + Down -> Ctrl + End) 实现 Cmd + Shift + Down
$!Space::Send "#s" ; 聚焦搜索 (Alt + Space -> Win + S) 实现 Cmd + Space

$#1::Send "^!1" ; 截图并复制 (Win + 1 -> Ctrl + Alt + 1) 实现 Cmd + 1
$#2::Send "^!2" ; 贴图 (Win + 2 -> Ctrl + Alt + 2) 实现 Cmd + 2
$#3::Send "^!3" ; 截图 (Win + 3 -> Ctrl + Alt + 3) 实现 Cmd + 3

~LAlt::Send "{Blind}{vkE8}"
~LAlt Up::
{
if (A_PriorKey = "LAlt")
{
Send "{LWin}"
}
}
#HotIf

🚀 如何使用

  1. 安装 AutoHotkey v2
  2. 创建一个新文件 MacKeys.ahk,将上述代码粘贴进去。
  3. 双击运行即可。
  4. (可选)将其放入 Windows 的启动文件夹,实现开机自启。

仓库地址放到这里,希望这对你有帮助!