Send[Raw|Input|Play|Event]: 发送按键和点击

发送模拟键击和鼠标点击到活动窗口.

Send Keys
SendRaw Keys
SendInput Keys
SendPlay Keys
SendEvent Keys

参数

Keys

要发送的按键序列. 和其他命令一样, 在首个参数前的逗号可以省略.

原始模式 - SendRaw{Raw}: 这些字符 ^+!#{} 解释为原义字符而不是转换, 如 {Enter} 不会转换为 Enter 键击, ^c 不会转换为 Control+C, 等等. 要在 SendInput, SendPlay, SendEvent 或 ControlSend 中使用原始模式, 请把 {Raw} 写在需发送的按键序列前面; 例如: SendInput {Raw}abc.

原始模式不影响转义序列, 变量引用表达式的解释. 例如, SendRaw, ``100`% 为发送字符 `100%. 当使用 ControlSend 时, 也需要转义原义的逗号 (`,).

文本模式 - {Text} [v1.1.27+]: 与原始模式类似, 除了不尝试将字符(除了 `r, `n, `t`b) 转换为键击外; 作为代替, 后备方法用于所有剩余的字符. 对于 SendEvent, SendInput 和 ControlSend, 这提高了可靠性, 因为字符对正确的修饰符状态的依赖性要小得多. 文本模式可以与 Blind(盲从) 模式结合使用, 以避免释放任何修饰键: Send {Blind}{Text}your text. 但是, 一些应用程序要求修饰键被释放.

`n, `r`r`n 都被转换为单独一次 Enter 键击, 不像普通模式和原始模式, 转换 `r`n 为两次 Enter 键击. `t 转换为 Tab`b 转换为 Backspace, 但所有其他字符都是不经转换直接发送的.

[v1.1.29+]: 与盲从模式类似, 文本模式忽略 SetStoreCapsLockMode(也就是说, CapsLock 的状态不会改变), 并且不等待 Win 键被释放. 这是因为文本模式通常不依赖于 CapsLock 的状态, 并且不能触发系统 Win+L 热键. 但是, 这仅适用于当 按键{Text}{Blind}{Text} 开头时.

普通模式: 不处于原始模式或文本模式时, 以下符号具有特殊含义: !+^#{}

这些修饰键 !+^# 仅影响紧跟着的下一个键. 若要发送修饰符本身对应的键, 将按键名称括在大括号中. 若要按下(按住) 或松开按键, 下面所示的单词 "down" 或 "up" 跟在按键名称的后面.

符号 按键 按下 松开 例子
! {Alt} {Alt down} {Alt up} Send !a 按下 ALT+A
+ {Shift} {Shift down} {Shift up} Send +abC 会发送文本"AbC"
Send !+a 按下 Alt+Shift+A
^ {Ctrl} {Ctrl down} {Ctrl up} Send ^{Home} 按下 Control+Home
# {LWin}
{RWin}
{LWin down}
{RWin down}
{LWin up}
{RWin up}
Send #e 按住 Win 键时按下字母 E
符号 含义
{ }

大括号用于括起键名和其他选项, 并发送特殊的原义字符. 例如, {Tab}Tab 键, 而 {!} 是原义的感叹号.

[v1.1.27+]: 将一个纯 ASCII 字母(a-z 或 A-Z) 括在大括号中强制它作为相应的虚拟键码发送, 即使该字符在当前键盘布局上不存在. 换句话说, Send a 产生字母 "a", 而 Send {a} , 根据键盘布局, 可能产生也可能不产生 "a". 有关详细信息, 请参阅下面的注释.

注意: 由于大写字母是通过发送 Shift 键产生的, 因此在某些程序中 Aa 会产生不同的效果. 例如, !A 按下 Alt+Shift+A!a 按下 Alt+A. 如果不确定, 请使用小写字母.

盲从模式 - {Blind}: 盲从模式通过禁用一些通常自动完成的任务, 从而使脚本更容易控制, 使事情按预期工作. {Blind} 必须是字符串中的第一个项目, 以启用盲从模式. 它有以下效果:

按键的重映射时, 盲从模式可以在内部使用. 例如, 重映射 a::b 会发生这样的情况: 1) 输入 "a" 时会映射为 "b"; 2) 输入大写字母 "A" 时映射为大写字母 "B"; 并且 3) 按下 Control+A 时映射为按下 Control+B.

SendRaw 或 ControlSendRaw 不支持 {Blind} ; 请使用 {Blind}{Raw} 代替.

SendPlay 不完全支持盲从模式, 尤其是在处理修饰键(Control, Alt, ShiftWin) 时.


SendInputSendPlay [v1.0.43+]: SendInput 和 SendPlay 与 Send 使用相同的语法, 但通常更快更可靠. 此外, 它们缓存了发送期间任何物理的键盘或鼠标活动, 这样避免了在发送时夹杂用户的键击. 可以使用 SendMode 让 Send 和 SendInput 或 SendPlay 执行相同的功能. 关于每种模式的更多细节, 请参阅下面的 SendInputSendPlay.

SendEvent [v1.0.43+]: SendEvent 和 1.0.43 之前版本的 Send 命令使用相同的方法发送键击. 键击发送的频率由 SetKeyDelay 决定. 默认情况下, SendSendEvent 是相同的; 但通过 SendMode 可以让它变成和 SendInputSendPlay 一样.

Key Names: 下表中列出了可以发送的特殊按键(每个按键名称必须用大括号括起来):

   
{F1} - {F24} 功能键. 例如: {F12} 表示 F12 键.
{!} !
{#} #
{+} +
{^} ^
{{} {
{}} }
{Enter} 主键盘上的 Enter
{Escape} 或 {Esc} ESCAPE
{Space} Space(仅对于要发送的按键序列开始或末尾的空格才需要这样表示, 而序列中间的空格是原义的)
{Tab} Tab
{Backspace} 或 {BS} Backspace(退格键)
{Delete} 或 {Del} Delete(删除键)
{Insert} 或 {Ins} Insert
{Up} (主键盘上的向上键)
{Down} (主键盘上的向下键)
{Left} (主键盘上的向左键)
{Right} (主键盘上的向右键)
{Home} Home(主键盘)
{End} End(主键盘)
{PgUp} PageUp(主键盘)
{PgDn} PageDown(主键盘)
   
{CapsLock} CapsLock(在 2k/XP 中使用 SetCapsLockState 更可靠). 发送 {CapsLock} 之前可能要求 SetStoreCapsLockMode Off.
{ScrollLock} ScrollLock(另请参阅: SetScrollLockState)
{NumLock} NumLock(另请参阅: SetNumLockState)
   
{Control} 或 {Ctrl} Control(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码)(译者注: 中性 Control 键 VK 11, SC 01D)
{LControl} 或 {LCtrl} Control 键(技术信息: 发送左边键的虚拟键码而不是中性键)(译者注: 左 Control 键 VK A2, SC 01D)
{RControl} 或 {RCtrl} Control
{Control down} 或 {Ctrl down} 按住 Control 键直到发送 {Ctrl up}. 要按住左边或右边的键, 请使用 {RCtrl down} 和 {RCtrl up}.
   
{Alt} Alt(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码)(译者注: 中性 Alt 键 VK 12, SC 038)
{LAlt} Alt 键(技术信息: 发送左边键的虚拟键码而不是中性键)(译者注: 左 Alt 键 VK A4, SC 038)
{RAlt} Alt 键(或 AltGr, 取决于键盘布局)
{Alt Down} 按住 Alt 键直到发送 {Alt up}. 要按住左边或右边的键, 请使用 {RAlt down} 和 {RAlt up}.
   
{Shift} Shift(技术信息: 发送中性键的虚拟键码和左边键的扫描码)(译者注: 中性 Shift 键 VK 10, SC 02A)
{LShift} Shift 键(技术信息: 发送左边键的虚拟键码而不是中性键)(译者注: 左 Shift 键 VK A0, SC 02A)
{RShift} Shift
{Shift down} 按住 Shift 键直到发送 {Shift up}. 要按住左边或右边的键, 请使用 {RShift down} 和 {RShift up}.
   
{LWin} Win
{RWin} Win
{LWin down} 按住左 Win 键直到发送 {LWin up}
{RWin down} 按住右 Win 键直到发送 {RWin up}
   
{AppsKey} Menu 键(调用右键点击或上下文菜单)
{Sleep} Sleep 键.
{ASC nnnnn}

发送 Alt+nnnnn 小键盘上的按键组合, 可以用来生成键盘上不存在的特殊字符. 要生成 ASCII 字符, 请指定一个介于 1 和 255 之间的数字. 要生成 ANSI 字符(在大多数语言中的标准), 请指定一个介于 128 和 255 之间的数字, 但需要在数字前加上一个前导零, 例如 {Asc 0133}.

要生成 Unicode 字符, 请指定一个介于 256 和 65535 之间的数字(不带前导零). 但是, 有些应用程序不支持这种方法. 对于替代方法, 请参阅下面的部分.

{U+nnnn}

[AHK_L 24+]: 发送 Unicode 字符, 其中 nnnn 为不包括 0x 前缀的字符的十六进制值. 在 AutoHotkey 的 Unicode 版本中通常不需要这么做, 因为它包含的 Send 和 ControlSend 自动支持 Unicode 文本.

使用 SendInput()WM_CHAR 发送这个字符而当前的发送模式无效. 以这种方式发送的字符通常不会触发快捷键或热键.

{vkXX}
{scYYY}
{vkXXscYYY}

发送一个虚拟按键为 XX 且扫描码为 YYY 的键击. 例如: Send {vkFFsc159}. 如果省略了 sc 或 vk 部分, 则会发送最适当的值.

XX 和 YYY 是十六进制值, 通常可以在主窗口的 View->Key history 菜单项找到. 另请参阅: 特殊按键

警告: 以这种方式组合 vk 和 sc, 仅在 Send 命令中有效. 在 [v1.1.27] 之前, 热键也允许使用, 但忽略 XX 后的任何非十六进制字符.

   
{Numpad0} - {Numpad9} 小键盘上的数字键(与 NumLock 打开时输入的一样). 例如: {Numpad5} 为数字 5.
{NumpadDot} .(小键盘上的点)(与 NumLock 打开时输入的一样).
{NumpadEnter} 小键盘上的 Enter
{NumpadMult} 小键盘上的 *(乘)
{NumpadDiv} 小键盘上的 /(除)
{NumpadAdd} 小键盘上的+(加)
{NumpadSub} 小键盘上的 -(减)
   
{NumpadDel} 小键盘上的 Delete 键(此键和后面的小键盘按键是在 NumLock 关闭时输入的)
{NumpadIns} 小键盘上的 Insert
{NumpadClear} 小键盘上的 Clear 键(通常在 Numlock 关闭时输入 '5' 的键).
{NumpadUp} 小键盘上的 (向上键)
{NumpadDown} 小键盘上的 向下键
{NumpadLeft} 小键盘上的 向左键
{NumpadRight} 小键盘上的 向右键
{NumpadHome} 小键盘上的 Home
{NumpadEnd} 小键盘上的 End
{NumpadPgUp} 小键盘上的 PageUp 向上翻页键
{NumpadPgDn} 小键盘上的 PageDown 向下翻页键
   
{Browser_Back} 按下浏览器的"后退"按钮
{Browser_Forward} 按下浏览器的"前进"按钮
{Browser_Refresh} 按下浏览器的"刷新"按钮
{Browser_Stop} 按下浏览器的"停止"按钮
{Browser_Search} 按下浏览器的"搜索"按钮
{Browser_Favorites} 按下浏览器的"收藏"按钮
{Browser_Home} 启动浏览器并打开主页
{Volume_Mute} 主音量静音/取消静音. 通常相当于 SoundSet, +1, , mute.
{Volume_Down} 减小主音量. 通常相当于 SoundSet -5.
{Volume_Up} 增加主音量. 通常相当于 SoundSet +5.
{Media_Next} 在媒体播放器中播放下一曲目
{Media_Prev} 在媒体播放器中播放前一曲目
{Media_Stop} 停止媒体播放器
{Media_Play_Pause} 播放/暂停媒体播放器
{Launch_Mail} 启动电子邮件程序
{Launch_Media} 启动媒体播放器
{Launch_App1} 启动用户程序 1
{Launch_App2} 启动用户程序 2
   
{PrintScreen} PrintScreen
{CtrlBreak} Ctrl+Break
{Pause} Pause
   
{Click [选项]}
[v1.0.43+]
使用与 Click 命令中相同的可用选项发送鼠标点击. 例如, Send {Click} 会在鼠标光标当前位置点击一次鼠标左键, 而 Send {Click 100, 200} 则在坐标 100, 200 处点击(这里的坐标模式取决于 CoordMode). 要移动鼠标而不点击, 请在坐标后指定 0; 例如: Send {Click 100, 200, 0}. 鼠标点击之间的延迟由 SetMouseDelay 决定(而不是 SetKeyDelay).
{WheelDown}, {WheelUp}, {WheelLeft}, {WheelRight}, {LButton}, {RButton}, {MButton}, {XButton1}, {XButton2} 向指针当前位置发送鼠标按钮事件(要指定位置和其他选项, 请使用上面的 {Click}). 在鼠标点击之间的延迟由 SetMouseDelay 决定. WheelLeft/Right 需要 [v1.0.48+], 并且在 Windows Vista 之前的操作系统中没有效果.
{Blind} 启用盲从模式, 通过禁用一些通常自动完成的任务, 从而使脚本更容易控制, 使事情按预期工作. 字符串 {Blind} 必须出现在字符串的开头.
{Raw}
[v1.0.43+]
启用原始模式, 这将导致以下字符被原义解释: ^+!#{}. {Raw} 可以不放在按键序列的开始处, 在按键序列中出现时, 它会影响它后面的剩余部分.
{Text}
[v1.1.27+]
启用文本模式, 发送字符流而不是按键. 像原始模式一样, 文本模式导致以下字符被解释为原义: ^+!#{}. 尽管字符串 {Text} 不需要在字符串的开始处出现, 但是一旦指定, 它将对字符串的其余部分生效.

重复或按住按键

重复键击: 用大括号括起按键名称和重复次数. 例如:

Send {DEL 4}  ; 按 4 次 Delete 键.
Send {S 30}   ; 发送 30 次大写字母 S.
Send +{TAB 4}  ; 按 4 次 Shift-Tab.

按住或释放按键: 把按键名称和单词 DownUp 写入到大括号中. 例如:

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 将产生 Control+A 的击键. DownTempDownR 可以用来覆盖这种行为. 除了修饰键(Control/Shift/Alt/Win) DownTempDownRDown 相同.

DownTemp 告诉随后的 Send, 按键不是永久按下的, 并且可以在按键调用时被释放. 例如, Send {Control DownTemp} 后面跟着 Send a 会产生一个正常的 A 键击, 而不是 Control+A 键击. 任何 Send 的使用都可能会永久释放修饰符, 所以 DownTemp 对于重映射修饰键是不理想的.

[v1.1.27+]: DownR (其中 "R" 表示重映射, 这是它的主要用途) 告诉后续的 send, 如果按键被自动释放, 当发送完成时应该再次按下. 例如, Send {Control DownR} 后面跟着 Send a会产生一个正常的 "a" 键击, 而不是 control-A 键击, 但是会使 Ctrl 键处于按下状态, 以便与键盘快捷键一起使用. 换句话说, DownR 有类似于物理按键的效果.

如果某个字符与当前键盘布局上的虚拟键不一致, 则不能"按下"或"释放". 例如, Send {μ up} 对大多数键盘布局没有效果, 而 Send {μ down} 等同于 Send μ.

一般说明

Characters vs. keys: 默认情况下, 先将字符转换为按键来发送字符. 如果这种转换是不可能的(即, 如果当前的键盘布局不包含产生该字符的键或键组合), 则通过以下回退方法之一发送字符:

注意: 使用上述方法发送字符通常不会触发键盘快捷键或热键.

[v1.1.27+]: 对于 a-zA-Z (纯 ASCII 字母) 范围内的字符, 每个当前键盘布局中不存在的字符可以作为字符或相应的虚拟键码(vk41-vk5A) 发送:

如果字母存在于当前的键盘布局中, 则始终以键盘布局与该字母关联的任何键码(除非使用文本模式, 在这种情况下该字符以其他方式发送) 的形式发送. 换句话说, 上面的部分只适用于非拉丁语的布局, 如俄语.

Modifier State: 当 Send 需要更改 WinAlt 修饰键的状态时(例如, 如果用户正在按住其中一个键), 它可能会注入更多击键(默认情况下为 Ctrl), 以防止出现开始菜单或窗口菜单, 有关详细信息, 请参阅 #MenuMaskKey.

BlockInput 与 SendInput/SendPlay 的比较: 尽管可以使用 BlockInput 命令防止用户输入的任何键击扰乱模拟键击流, 但使用 SendInputSendPlay 通常更好, 这样键击和鼠标点击会保持连续. 这是由于与 BlockInput 不同, SendInput/Play 不会丢弃发送期间用户输入的内容; 作为替代, 这些键击被缓冲起来在之后发送.

发送大量键击时, 使用延续片段可以提高可读性和可维护性.

由于操作系统不允许程序模拟 Ctrl+Alt+Delete 组合键, 所以执行像 Send ^!{Delete} 的命令不会产生效果.

当活动窗口以管理权限运行而当前脚本不是时, Send 在 Windows Vista 或更高版本中可能没有效果. 这是由于用户接口和特权分离的安全机制.

SendInput [v1.0.43+]

由于 SendInput 突出的速度和可靠性, 通常为发送键击和鼠标点击的首选方法. 在大多数情况下, SendInput 是近乎瞬时发送的, 即使在发送长字符串也是如此. 由于 SendInput 如此快速, 所以也更可靠, 因为这样其他一些窗口更没有机会出乎意料地弹出并打断正发送的键击. 可靠性进一步提升是通过把用户在 SendInput 发送期间输入的内容推迟的情况而言.

与其他发送模式不同, 操作系统限制 SendInput 每次只能发送大约 5000 个字符(此限制可能因操作系统版本和性能设置而有所不同). 超过此限制的字符和事件不会被发送.

注意: SendInput 会忽略 SetKeyDelay, 因为在这种发送模式中操作系统不支持延迟. 但是, 在后面描述的情况中当 SendInput 恢复到 SendEvent 时, 它会使用 SetKeyDelay -1, 0(但如果 SendEvent 的按键延迟为 -1, -1 时, 则使用 -1, -1). 当 SendInput 恢复为 SendPlay 时, 它使用 SendPlay 的按键延迟.

如果执行 SendInput 脚本外的其他脚本安装了低级键盘钩子, 则 SendInput 会自动恢复为 SendEvent(或 SendPlay, 当 SendMode InputThenPlay 有效的时候). 这是由于外部钩子的存在让 SendInput 失去了所有的优势, 使它不如 SendPlay 和 SendEvent 两者. 然而, 在 [AutoHotkey v1.0.43+] 之前的版本中 SendInput 无法检测到底层键盘钩子, 在这种情况下将不会自动恢复使得比 SendPlay/Event 更不可靠.

当 SendInput 使用像 {Click} 这样的方法发送鼠标点击, 并且 CoordMode Mouse, Relative 有效时(默认), 则每次点击都会相对于发送开始时的那个活动窗口. 因此, 如果 SendInput 有意地激活另一个窗口(通过类似 alt-tab 的方法), 那么这个命令中后续点击的坐标将变成错误的, 因为它们仍然相对于原来的活动窗口而不是新的.

SendPlay [v1.0.43+]

警告: SendPlay 在 UAC 启用时完全失效, 即使是使用管理员权限运行脚本. 详情参见 FAQ.

比起其他模式 SendPlay 最大的优势是具有在相当多种游戏中 "play back" 键击和鼠标点击能力. 例如, 某种特殊的游戏可能仅接受 SendPlay 选项热字串. 但是, SendPlay 在启用了用户账户控制的 Windows Vista 或更高版本中则可能没有效果, 即使以管理员运行脚本. 下面的脚本提供了此问题的变通解决方法: https://www.autohotkey.com/forum/topic75595.html.

在三种发送模式中, SendPlay 是最不常用的, 因为它本身并不模拟键击和鼠标点击. 作为替代, 它制造一系列事件(消息) 直接流向活动窗口(类似于 ControlSend, 但在更低的层面). 因此 SendPlay 不会触发热键或热字串.

SendInput 一样, SendPlay 的键击不会夹杂用户输入的内容. 因此, 如果用户碰巧在 SendPlay 发送期间输入了一些内容, 则它们会被延迟到发送完后.

尽管 SendPlay 明显比 SendInput 慢, 但它通常比传统的 SendEvent 模式更快(即使在 KeyDelay 为 -1 时).

如果安装了键盘钩子, 则在 SendPlay 发送期间会自动屏蔽 Win 键(LWin 和 RWin). 这样避免了在发送期间当用户无意按了 Win 键时显示开始菜单. 与之相比, LWin 和 RWin 之外的其他按键不需要屏蔽, 因为操作系统会自动把它们延迟到 SendPlay 执行完后(通过缓冲).

SendPlay 不使用 SetKeyDelaySetMouseDelay 的标准设置. 作为替代, 它默认没有延迟, 这可以像下面例子演示的那样改变:

SetKeyDelay, 0, 10, Play  ; 请注意 0 和 -1 在 SendPlay 模式中是一样的.
SetMouseDelay, 10, Play

SendPlay 不能切换 CapsLock, NumLockScrollLock 按键的状态. 同样地, 如果键击发送到脚本自身的窗口时, 则它才能改变由 GetKeyState 获取的按键状态. 即使在此时, 对左/右修饰键的任何改变(例如 RControl) 只能通过它们的中性副本检测到(例如 Control). 并且, SendPlay 还有在 SendMode 页面描述的其他限制.

SendInputSendEvent 不同, 用户通过按下 Control+Alt+DelControl+Escape 打断 SendPlay 的发送. 这种情况发生时, 剩余的键击不会被发送, 不过脚本会像 SendPlay 正常结束一样继续执行.

尽管 SendPlay 能发送 LWin 和 RWin 事件, 但它们被直接发送到活动窗口而不执行它们原本的操作系统功能. 要变通解决此问题, 请使用 SendEvent. 例如, SendEvent #r 会显示开始菜单的运行对话框.

相关

SendMode, SetKeyDelay, SetStoreCapsLockMode, 转义序列(例如 `%), ControlSend, BlockInput, 热字串, WinActivate

示例

#1

Send Sincerely,{enter}John Smith  ; 输入两行的签名.
Send !fs ; 选择 File->Save 菜单 (Alt+F 后面跟着 S).
Send {End}+{Left 4} ; 跳到文本的末尾然后发送四次 shift 和左方向键组合的键击.
SendInput {Raw}A long series of raw characters sent via the fastest method. ; 有关详情, 请参阅 {Raw}.