发送模拟键击和鼠标点击到活动窗口.
Send Keys SendText Keys SendInput Keys SendPlay Keys SendEvent Keys
类型: 字符串
要发送的按键序列.
默认情况下(也就是说, 如果既不使用 SendText, 也不使用原始模式或文本模式), 字符 ^+!#{} 具有特殊含义. 字符 ^+!# 分别代表修饰符键 Ctrl, Shift, Alt 和 Win. 他们仅影响紧跟着的下一个键. 若要发送修饰符本身对应的键, 将按键名称括在大括号中. 若要按下(按住) 或松开按键, 下面所示的单词 "down" 或 "up" 跟在按键名称的后面.
^+!#{}
^+!#
Send "^{Home}"
Send "+abC"
Send "!+a"
Send "!a"
Send "#e"
注意: 由于大写字母是通过发送 Shift 产生的, 因此在某些程序中 A 和 a 会产生不同的效果. 例如, !A 按下 Alt+Shift+A, 而 !a 按下 Alt+A. 如果不确定, 请使用小写字母.
A
a
!A
!a
字符 {} 用于括起键名和其他选项, 并发送特殊的原义字符. 例如, {Tab} 是 Tab, 而 {!} 是原义的感叹号.
{}
{Tab}
{!}
将一个纯 ASCII 字母(a-z 或 A-Z) 括在大括号中强制它作为相应的虚拟键码发送, 即使该字符在当前键盘布局上不存在. 换句话说, Send a 产生字母 "a", 而 Send {a} 根据键盘布局, 可能产生也可能不产生 "a". 有关详情, 请参阅下面的注释.
Send a
Send {a}
Send: 默认情况下, Send 等同于 SendInput; 但是可以通过 SendMode 使其等同于 SendEvent 或 SendPlay.
SendText: 类似于 Send, 除了 Keys 中的所有字符都按原义解释. 有关详情, 请参阅文本模式.
SendInput 和 SendPlay: SendInput 和 SendPlay 使用与 SendEvent 相同的语法, 但通常更快更可靠. 此外, 它们在发送过程中缓冲任何物理键盘或鼠标活动, 这可以防止用户的击键与发送的击键穿插在一起. 通过 SendMode 可以使 Send 等同于 SendInput 或 SendPlay. 有关每种模式的更多信息, 请参阅下面的 SendInput 和 SendPlay.
SendEvent: SendEvent 使用 Windows keybd_event 函数发送键击(有关详情, 请在 Microsoft Docs 搜索). 发送击键的速率由 SetKeyDelay 决定. 通过 SendMode 可以使 Send 等同于 SendEvent 或 SendPlay.
以下模式影响 Keys 中字符的解释, 或键发送函数(例如 Send, SendInput, SendPlay, SendEvent 和 ControlSend) 的行为. 这些模式必须在 Keys 中指定 {x}, 其中 x 可以是 Raw, Text 或 Blind. 例如, {Raw}.
{x}
{Raw}
可以使用 {Raw} 启用原始模式, 这会导致所有后续字符, 包括特殊字符 ^+!#{}, 都按原义进行解释, 如 {Enter} 不会转换为 Enter, ^c 不会转换为 Ctrl+C, 等等. 例如, Send "{Raw}{Tab}" 发送 {Tab}, 而不是 Tab.
{Enter}
^c
Send "{Raw}{Tab}"
原始模式不影响转义序列和表达式的解释. 例如, Send "{Raw}``100`%" 发送字符 `100%.
Send "{Raw}``100`%"
`100%
可以使用 {Text}, SendText 或 ControlSendText 来启用文本模式, 与原始模式类似, 不同之处在于不会尝试将字符(`r, `n, `t 和 `b 除外) 转换为键码; 作为代替, 后备方法适用于所有剩余的字符. 对于 SendEvent, SendInput 和 ControlSend, 这提高了可靠性, 因为字符对正确的修饰符状态的依赖性要小得多. 文本模式可以与盲从模式结合使用, 以避免释放任何修饰键: Send "{Blind}{Text}your text". 但是, 一些应用程序会要求修饰键被释放.
{Text}
`r
`n
`t
`b
Send "{Blind}{Text}your text"
`n, `r 和 `r`n 都被转换为一次单独的 Enter, 不像普通模式和原始模式, 转换 `r`n 为两次 Enter. `t 转换为 Tab, 而 `b 转换为 Backspace, 但所有其他字符都是不经转换直接发送的.
`r`n
与盲从模式类似, 文本模式忽略 SetStoreCapsLockMode(也就是说, 不会改变 CapsLock 的状态), 并且不等待 Win 被释放. 这是因为文本模式通常不依赖于 CapsLock 的状态, 并且不能触发系统 Win+L 热键. 但是, 这仅适用于当 Keys 以 {Text} 或 {Blind}{Text} 开头时.
{Blind}{Text}
可以使用 {Blind} 启用盲从模式, 该模式通过禁用通常自动执行的许多操作来使脚本按预期运行, 从而赋予脚本更多控制权. 要启用盲从模式, {Blind} 必须是字符串中的第一个项目. 它具有以下效果:
{Blind}
+s::Send "{Blind}abc"
^space::Send "{Ctrl up}"
^space::Send "{Blind}{Ctrl up}"
单词 "Blind" 后面可以用一个或多个修饰符号(!#^+) 以便在需要时自动释放这些修饰符. 例如, *^a::Send "{Blind^}b" 在按下 Ctrl+Shift+A 时, 将发送 Shift+B 而不是 Ctrl+Shift+B. {Blind!#^+} 可以在需要的时候释放所有的修饰符, 但是会启用盲从模式的其他效果.
!#^+
*^a::Send "{Blind^}b"
{Blind!#^+}
在重映射按键时, 盲从模式可以在其内部使用. 例如, 重映射 a::b 会发生这样的情况: 1) 输入 "a" 时会映射为 "b"; 2) 输入大写字母 "A" 时映射为大写字母 "B"; 并且 3) 按下 Ctrl+A 时映射为按下 Ctrl+B. 如果任何修饰符指定为源按键(包括 Shift 如果源按键是大写字母), 则如上所述, 这些修饰符被排除在外. 例如 ^a::b 产生的是正常的 B, 而不是 Ctrl+B.
a::b
^a::b
SendText 或 ControlSendText 不支持 {Blind}; 请使用 {Blind}{Text} 代替.
SendPlay 不完全支持盲从模式, 尤其是在处理修饰键时(Ctrl, Alt, Shift 和 Win).
下表中列出了可以发送的特殊按键(每个按键名称必须用大括号括起来):
SetStoreCapsLockMode False
发送 Alt+nnnnn 小键盘上的按键组合, 可以用来生成键盘上不存在的特殊字符. 要生成 ASCII 字符, 请指定一个介于 1 和 255 之间的数字. 要生成 ANSI 字符(在大多数语言中的标准), 请指定一个介于 128 和 255 之间的数字, 但需要在数字前加上一个前导零, 例如 {Asc 0133}..
要生成 Unicode 字符, 请指定一个介于 256 和 65535 之间的数字(不带前导零). 但是, 有些应用程序不支持这种方法. 对于替代方法, 请参阅下面的部分.
发送 Unicode 字符, 其中 nnnn 为字符的不包括 0x 前缀的十六进制值. 通常不需要这么做, 因为 Send 和 ControlSend 自动支持 Unicode 文本.
会使用 SendInput() 或 WM_CHAR 来发送字符, 并且当前的发送模式没有效果. 以这种方式发送的字符通常不会触发快捷键或热键.
{vkXX} {scYYY} {vkXXscYYY}
发送虚拟键为 XX 和扫描码为 YYY 的按键. 例如: Send "{vkFFsc159}". 如果省略 sc 或 vk 部分, 则发送最合适的值.
Send "{vkFFsc159}"
XX 和 YYY 的值是十六进制的, 通常可以从主窗口的 View->Key history 菜单项中确定. 另请参阅: 特殊按键
警告: 以这种方式组合 vk 和 sc 仅在 Send 有效.
SoundSetMute -1
SoundSetVolume -5
SoundSetVolume "+5"
Send "{Click}"
Send "{Click 100 200}"
Send "{Click 100 200 0}"
LButton 和 RButton 分别对应鼠标的主按钮和次按钮. 通常鼠标的主按钮(LButton) 在左边, 但是用户可以通过系统设置来交换按钮.
重复键击: 用大括号括起按键名称和重复次数. 例如:
Send "{DEL 4}" ; 按 4 次 Delete 键. Send "{S 30}" ; 发送 30 次大写字母 S. Send "+{TAB 4}" ; 按 4 次 Shift-Tab.
按住或释放按键: 用大括号括起按键名称和单词 Down 或 Up. 例如:
Send "{b down}{b up}" Send "{TAB down}{TAB up}" Send "{Up down}" ; 按下向上键. Sleep 1000 ; 按住 1 秒. Send "{Up up}" ; 释放向上键.
使用上面的方法按住一个按键后, 这个期间它不会像您实际按住这个按键一样自动重复(这是由于自动重复是一个驱动/硬件的特性). 不过, 可以使用 Loop 来模拟自动重复. 下面的例子中发送 20 次 tab 键击:
Loop 20 { Send "{Tab down}" ; 自动重复由连续的按下事件组成(没有弹起事件). Sleep 30 ; 在两次键击之间的毫秒数(或使用 SetKeyDelay 设置). } Send "{Tab up}" ; 松开按键.
默认情况下, 如果一个修饰键在发送时被 "按下", 则 Send 不会自动释放该修饰键(Control, Shift, Alt 和 Win) . 例如, 如果用户物理按下 Ctrl 时, Send "a" 的行为类似于 Send "{Blind}{Ctrl up}a{Ctrl down}", 但 Send "{Ctrl Down}" 后面接着 Send "a" 将产生 Ctrl+A. DownTemp 和 DownR 可以用来覆盖这种行为. DownTemp 和 DownR 与 Down 具有同样的效果, 除了修饰键(Control, Shift, Alt 和 Win).
Send "a"
Send "{Blind}{Ctrl up}a{Ctrl down}"
Send "{Ctrl Down}"
DownTemp 告诉后续的发送, 该键不是永久按下的, 只要有按键需要就可以释放. 例如, 在发送 Send "{Control DownTemp}" 之后, 再 Send "a" 将产生一个正常的 A, 而不是 Ctrl+A. 任何使用 Send 的方法都有可能永久地释放修饰键, 所以 DownTemp 并不是重映射修饰键的理想选择.
Send "{Control DownTemp}"
DownR(其中 "R" 表示重映射, 这是它的主要用途) 告诉后续的发送, 如果该键被自动释放, 则应在发送结束后再次按下. 例如, Send "{Control DownR}" 后面跟着 Send "a" 会产生一个正常的 A, 而不是 Ctrl+A, 但会让 Ctrl 处于被按下的状态, 以便用于键盘快捷键. 换句话说, DownR 有类似于物理按下按键的效果.
Send "{Control DownR}"
如果某个字符与当前键盘布局上的虚拟键不一致, 则不能 "按下" 或 "释放". 例如, Send "{μ up}" 对大多数键盘布局没有效果, 而 Send "{μ down}" 等同于 Send "μ".
Send "{μ up}"
Send "{μ down}"
Send "μ"
字符 vs. 按键: 默认情况下, 先将字符转换为按键来发送字符. 如果这种转换是不可能的(即, 如果当前的键盘布局不包含产生该字符的键或键组合), 则通过以下回退方法之一来发送字符:
注意: 使用上述方法发送字符通常不会触发键盘快捷键或热键.
对于 a-z 或 A-Z(纯 ASCII 字母) 范围内的字符, 每个当前键盘布局中不存在的字符可以作为字符或相应的虚拟键码(vk41-vk5A) 发送:
Send "{Raw}Regards"
{Ctrl down}c{Ctrl up}
{c}
{vk43}
如果字母存在于当前的键盘布局中, 那么它总是以布局与该字母相关联的键码发送(除非使用了文本模式, 在这种情况下, 该字符将通过其他方式发送). 换句话说, 上面的部分只适用于非拉丁语系的布局, 如俄语.
修饰键状态: 当 Send 需要改变 Win 或 Alt 修饰键的状态时(比如用户按住其中一个键), 它可能会注入额外的按键(默认为 Ctrl) 来阻止开始菜单或窗口菜单的出现. 有关详情, 请参阅 A_MenuMaskKey.
BlockInput 对比 SendInput/SendPlay: 尽管 BlockInput 函数可以用来防止用户物理输入的任何按键破坏模拟按键的流, 但通常最好使用 SendInput 或 SendPlay 这样按键和鼠标点击就不会中断. 这是因为与 BlockInput 不同的是, SendInput/Play 不会在发送过程中丢弃用户输入的内容; 相反, 这样的按键会被缓冲并在之后发送.
当发送大量的按键时, 可以使用延续片段来提高可读性和可维护性.
由于操作系统不允许模拟 Ctrl+Alt+Del 组合, 所以类似 Send "^!{Delete}" 这样的操作是没有效果的.
Send "^!{Delete}"
当活动窗口以管理身份运行而当前脚本不是时, Send 可能没有效果. 这是由于一种叫做用户界面特权隔离的安全机制造成的.
一般情况下, SendInput 是发送按键和鼠标点击的首选方法, 因为它的速度和可靠性都很高. 在大多数情况下, SendInput 几乎是瞬间完成的, 即使是发送长字符串时也是如此. 由于 SendInput 的速度如此之快, 它的可靠性也更高, 因为这样其他一些窗口更没有机会出乎意料地弹出并打断按键. 用户在 SendInput 过程中输入的任何东西都会被推迟到之后再进行, 从而进一步提高了可靠性.
与其他发送模式不同, 操作系统限制 SendInput 每次只能发送大约 5000 个字符(此限制可能因操作系统版本和性能设置而有所不同). 超过此限制的字符和事件不会被发送.
注意: SendInput 会忽略 SetKeyDelay, 因为在这种发送模式中操作系统不支持延迟. 但是, 在后面描述的情况中, 当 SendInput 恢复到 SendEvent 时, 它会使用 SetKeyDelay -1, 0(但如果 SendEvent 的按键延迟为 -1,-1 时, 则使用 -1,-1). 当 SendInput 恢复为 SendPlay 时, 它使用 SendPlay 的按键延迟.
SetKeyDelay -1, 0
-1,-1
如果执行 SendInput 的脚本 以外的 脚本安装了低级键盘钩子, 则 SendInput 会自动恢复为 SendEvent(或当 SendMode "InputThenPlay" 生效时为 SendPlay). 这是由于外部钩子的存在让 SendInput 失去了所有的优势, 使它不如 SendPlay 和 SendEvent 两者. 然而, 由于 SendInput 无法检测到除 AutoHotkey v1.0.43+ 以外的程序中的低级钩子, 所以在这些情况下它不会还原, 使得它的可靠性不如 SendPlay/Event.
SendMode "InputThenPlay"
当 SendInput 使用像 {Click} 这样的方法发送鼠标点击, 并且 CoordMode "Mouse", "Window" 或 CoordMode "Mouse", "Client" 有效时(默认的), 则每次点击都会相对于发送开始时的那个活动窗口. 因此, 如果 SendInput 有意地激活另一个窗口(通过类似 alt-tab 的方法), 那么这个命令中后续点击的坐标将变成错误的, 因为它们仍然相对于原来的活动窗口而不是新的.
CoordMode "Mouse", "Window"
CoordMode "Mouse", "Client"
警告: 如果启用了 UAC, 即使脚本以管理员身份运行, SendPlay 也可能没有效果. 有关详情, 请参阅 FAQ.
SendPlay 最大的优势在于它能在更多的游戏中 "回放" 按键和鼠标点击. 例如, 某款游戏只有在有 SendPlay 选项的情况下才能接受热字串.
在这三种发送模式中, SendPlay 是最特别的, 因为它本身并不模拟按键和鼠标点击. 相反, 它创建了一系列的事件(消息), 直接流向活动窗口(类似于 ControlSend, 但级别较低). 因此, 不会触发热键或热字串.
和 SendInput 一样, SendPlay 的按键与用户键入的按键互不干扰. 因此, 如果用户在 SendPlay 期间碰巧输入了一些东西, 这些键程会被推迟到之后.
虽然 SendPlay 比 SendInput 要慢很多, 但它通常比传统的 SendEvent 模式要快(即使 KeyDelay 为 -1 时, 也是如此).
如果安装了键盘钩子, 则在 SendPlay 发送期间会自动屏蔽 Win(LWin 和 RWin). 这样避免了在发送期间当用户无意按了 Win 键时显示开始菜单. 与之相比, LWin 和 RWin 之外的其他按键不需要屏蔽, 因为操作系统会自动把它们延迟到 SendPlay 执行完后(通过缓冲).
SendPlay 不使用 SetKeyDelay 和 SetMouseDelay 的标准设置. 相反, 它默认为无延迟, 可以按照下面的例子来改变:
SetKeyDelay 0, 10, "Play" ; 注意 0 和 -1 在 SendPlay 模式中是一样的. SetMouseDelay 10, "Play"
SendPlay 无法打开或关闭 CapsLock, NumLock 或 ScrollLock. 同样, 它也无法改变 GetKeyState 所看到的键的状态, 除非按键被发送到脚本自己的一个窗口. 即使如此, 任何对左/右修饰键(例如 RControl) 的改变也只能通过它们的中性对应键(例如 Control) 来检测. 此外, SendPlay 还有其他限制, 在 SendMode 页面上有描述.
与 SendInput 和 SendEvent 不同, 用户可以通过按下 Ctrl+Alt+Del 或 Ctrl+Esc 来中断 SendPlay. 当这种情况发生时, 剩余的按键不会被发送, 但是脚本会继续执行, 就像 SendPlay 已经正常完成一样.
虽然 SendPlay 可以发送 LWin 和 RWin 事件, 但是它们会直接发送到活动窗口, 而不是执行它们的在操作系统中的原生功能. 要解决这个问题, 请使用 SendEvent. 例如, SendEvent "#r" 将显示开始菜单的运行对话框.
SendEvent "#r"
SendMode, SetKeyDelay, SetStoreCapsLockMode, 转义序列(例 `n), ControlSend, BlockInput, 热字串, WinActivate
输入两行签名.
Send "Sincerely,{enter}John Smith"
选择 File->Save 菜单(Alt+F 后面跟着 S).
Send "!fs"
到文本的末尾然后发送四次 shift 和左方向键组合的键击.
Send "{End}+{Left 4}"
通过最快的方法发送一长串原始字符.
SendInput "{Raw}A long series of raw characters sent via the fastest method."