Send / SendRaw / SendInput / SendPlay / SendEvent: 发送按键和点击

优质
小牛编辑
127浏览
2023-12-01

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

Send Keys
SendRaw Keys
SendInput Keys
SendPlay Keys
SendEvent Keys

参数

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

原始模式: SendRaw 命令会原样发送所有字符, 而不把 {Enter} 转换成 ENTER 键击, 把 ^c 转换成 Control-C, 等等. 不过, 转义系列, 变量引用和表达式的一般规则仍然适用, 因为它们在命令执行前就已经被处理了. 要在 SendInput、SendPlay 或 SendEvent 中使用原始模式,请把 {Raw} 写在需发送的按键序列前面;例如:SendInput {Raw}abc

普通模式: 不处于原始模式时, 下列字符被看成是修饰键 (这些修饰键仅影响紧跟着的下一个键):

!: 发送 ALT 键击. 例如,Send This is text!a 将发送按键序列“This is text”并接着按下 ALT+a。: 在某些程序中 !A 和 !a 会产生不同的效果. 这是由于 !A 按了 ALT+SHIFT+A 而 !a 按了 ALT+a. 如果不确定, 请使用小写字母.

+: 发送 SHIFT 键击. 例如,Send +abC 会发送文本“AbC”,而 Send !+a 会按下 ALT+SHIFT+a。

^: 发送 CONTROL 键击. 例如,Send ^!a 会按下 CTRL+ALT+a,而 Send ^{Home} 则发送 CONTROL+HOME。: 在某些程序中 ^A 和 ^a 会产生不同的效果. 这是由于 ^A 按了 CONTROL+SHIFT+A 而 ^a 按了 CONTROL+a. 如果不确定, 请使用小写字母.

#:发送 WIN 键击,因此 Send #e 会在按住 Windows 键时按下字母“e”。


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

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

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

按键名称生成的键击
{F1} - {F24}功能键. 例如: {F12} 表示 F12 键.
{!}!
{#}#
{+}+
{^}^
{{}{
{}}}
{Enter}主键盘上的 ENTER 键
{Escape} 或 {Esc}ESCAPE
{Space}SPACE (仅对于要发送的按键序列开始或末尾的空格才需要这样表示, 而序列中间的空格是原义的)
{Tab}TAB
{Backspace} 或 {BS}退格键
{Delete} 或 {Del}Delete
{Insert} 或 {Ins}Insert
{Up}主键盘上的向上键
{Down}主键盘上的向下键
{Left}主键盘上的向左键
{Right}主键盘上的向右键
{Home}主键盘上的 Home 键
{End}主键盘上的 End 键
{PgUp}主键盘上的向上翻页键
{PgDn}主键盘上的向下翻页键
  
{CapsLock}CapsLock(在 2k/XP 中使用 SetCapsLockState 更可靠)。发送 {CapsLock} 之前可能要求 SetStoreCapslockMode Off.
{ScrollLock}ScrollLock (另请参阅: SetScrollLockState)
{NumLock}NumLock (另请参阅: SetNumLockState)
  
{Control} 或 {Ctrl}CONTROL (技术信息: 发送中性的虚拟按键代码和左边的扫描码, 即在 vkXXscYYY 中, XX 为中性的而 YYY 为左边的扫描码)
{LControl} 或 {LCtrl}左 CONTROL 键(技术信息:发送左边的虚拟按键而非中性的那个)
{RControl} 或 {RCtrl}右 CONTROL 键
{Control Down} 或 {Ctrl Down}按住 CONTROL 键直到发送 {Ctrl Up}. 要按住左边或右边的键,请使用 {RCtrl Down} 和 {RCtrl Up}。
  
{Alt}ALT (技术信息: 发送中性的虚拟按键和左边的扫描码)
{LAlt}左 ALT 键(技术信息:发送左边的虚拟按键而不是中性的那个)
{RAlt}右 ALT 键 (或 AltGr, 取决于键盘布局)
{Alt Down}按住 ALT 键直到发送 {Alt Up}. 要按住左边或右边的键,请使用 {RAlt Down} 和 {RAlt Up}。
  
{Shift}SHIFT (技术信息: 发送中性的虚拟按键和左边的扫描码)
{LShift}左 SHIFT 键(技术信息:发送左边的虚拟按键而不是中性的那个)
{RShift}右 SHIFT 键
{Shift Down}按住 SHIFT 键直到发送 {Shift Up}. 要按住左边或右边的键,请使用 {RShift Down} 和 {RShift Up}。
  
{LWin}左 Windows 键
{RWin}右 Windows 键
{LWin Down}按住左 Windows 键直到发送 {LWin Up}
{RWin Down}按住右 Windows 键直到发送 {RWin Up}
  
{AppsKey}Windows Appskey (调用右键点击或上下文菜单)
{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 菜单项找到. 另请参阅: 特殊按键

  
{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}小键盘上的向上翻页键
{NumpadPgDn}小键盘上的向下翻页键
  
{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}Print Screen
{CtrlBreak}Ctrl+break
{Pause}暂停
  
{Click [选项]}
[v1.0.43+]
使用与 Click 命令 中相同的可用选项发送鼠标点击. 例如,{Click} 会在鼠标光标当前位置点击一次鼠标左键,而 {Click 100, 200} 则在坐标 100, 200 处点击(这里的坐标模式取决于 CoordMode)。要移动鼠标而不点击,请在坐标后指定 0;例如:{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} 时, 如果 Alt/Control/Shift/Win 在发送开始时为按下的状态则不松开. 例如,热键 +s::Send {Blind}abc 将发送 ABC 而不是 abc,因为用户按住了 Shift 键。

{Blind} 还会忽略 SetStoreCapslockMode; 即不会改变 Capslock 的状态. 最后, {Blind} 会忽略发送的键击中的额外控制功能; 这样的键击中可以避免后面的情况: 1) 发送 LWin/RWin 键击时出现开始菜单; 2) 发送 Alt 键击时激活菜单栏.

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

SendRaw 和 ControlSendRaw 不支持 {Blind}. 此外, SendPlay 也不完全支持这种模式, 尤其是在处理修饰键 (Control, Alt, Shift 和 Win) 时.

{Raw}
[v1.0.43+]
准确按照原样发送键击,而不把 {Enter} 转换成 ENTER 键击,把 ^c 转换成 Control-C 等等。{Raw} 可以不放在按键序列的开始处, 在按键序列中出现时, 它会影响它后面的剩余部分.

重复或按住按键

重复键击: 把需要重复的按键名称和重复次数写入到大括号中. 例如:

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}  ; 松开按键.

还可以使用单词 DownTemp. 除了对修饰键 (Control/Shift/Alt/Win) 有区别外它的效果与 Down 相同. 在那些情况下, DownTemp 告知后续的 send 命令这个键不是永久按下, 并可能在需要时随时松开. 例如,Send {Control DownTemp} 之后接着执行 Send a 会产生普通的“a”键击,而不是 control-A 键击。

一般说明

Send 命令支持发送的字符没有特殊限制。对于当前键盘布局中不存在的字符,根据 AutoHotkey 版本的不同可以通过发送 Unicode 字符包或 Alt+nnnnn 组合来模拟。在 AutoHotkey 的 Unicode 版本中直接支持文本形式的 Unicode 字符,而在所有版本中都可以使用 {U+nnnn} 表示法。

BlockInput 与 SendInput/SendPlay 的比较: 尽管可以使用 BlockInput 命令防止用户输入的任何键击扰乱模拟键击流, 但使用 SendInput 或 SendPlay 通常更好, 这样键击和鼠标点击会保持连续. 这是由于与 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 最大的优势是具有在相当多种游戏中 "play back" 键击和鼠标点击能力. 例如, 某种特殊的游戏可能仅接受 SendPlay 选项热字串. 但是, SendPlay 在启用了用户账户控制的 Windows Vista 或更高版本中则可能没有效果, 即使以管理员运行脚本. 下面的脚本提供了此问题的变通解决方法: http://www.autohotkey.com/forum/topic75595.html.

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

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

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

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

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

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

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

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

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

相关

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

示例

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 (SendInput).