发送模拟键击和鼠标点击到活动窗口.
Send Keys SendText Keys SendInput Keys SendPlay Keys SendEvent Keys
类型: 字符串
要发送的按键序列.
默认情况下(也就是说, 如果既不使用 SendText, 也不使用原始模式或文本模式), 字符 ^+!#{}
具有特殊含义. 字符 ^+!#
分别代表修饰符键 Ctrl, Shift, Alt 和 Win. 他们仅影响紧跟着的下一个键. 若要发送修饰符本身对应的键, 将按键名称括在大括号中. 若要按下(按住) 或松开按键, 下面所示的单词 "down" 或 "up" 跟在按键名称的后面.
符号 | 按键 | 按下 | 松开 | 示例 |
---|---|---|---|---|
^ | {Ctrl} | {Ctrl down} | {Ctrl up} | Send "^{Home}" 按下 Ctrl+Home |
+ | {Shift} | {Shift down} | {Shift up} | Send "+abC" 发送文本 "AbC"Send "!+a" 按下 Alt+Shift+A |
! | {Alt} | {Alt down} | {Alt up} | Send "!a" 按下 Alt+A |
# | {LWin} {RWin} |
{LWin down} {RWin down} |
{LWin up} {RWin up} |
Send "#e" 按住 Win 键时, 按下字母 E |
注意: 由于大写字母是通过发送 Shift 产生的, 因此在某些程序中 A
和 a
会产生不同的效果. 例如, !A
按下 Alt+Shift+A, 而 !a
按下 Alt+A. 如果不确定, 请使用小写字母.
字符 {}
用于括起键名和其他选项, 并发送特殊的原义字符. 例如, {Tab}
是 Tab, 而 {!}
是原义的感叹号.
将一个纯 ASCII 字母(a-z 或 A-Z) 括在大括号中强制它作为相应的虚拟键码发送, 即使该字符在当前键盘布局上不存在. 换句话说, Send a
产生字母 "a", 而 Send {a}
根据键盘布局, 可能产生也可能不产生 "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}
.
可以使用 {Raw}
启用原始模式, 这会导致所有后续字符, 包括特殊字符 ^+!#{}
, 都按原义进行解释, 如 {Enter}
不会转换为 Enter, ^c
不会转换为 Ctrl+C, 等等. 例如, Send "{Raw}{Tab}"
发送 {Tab}
, 而不是 Tab.
原始模式不影响转义序列和表达式的解释. 例如, Send "{Raw}``100`%"
发送字符 `100%
.
可以使用 {Text}
, SendText 或 ControlSendText 来启用文本模式, 与原始模式类似, 不同之处在于不会尝试将字符(`r
, `n
, `t
和 `b
除外) 转换为键码; 作为代替, 后备方法适用于所有剩余的字符. 对于 SendEvent, SendInput 和 ControlSend, 这提高了可靠性, 因为字符对正确的修饰符状态的依赖性要小得多. 文本模式可以与盲从模式结合使用, 以避免释放任何修饰键: Send "{Blind}{Text}your text"
. 但是, 一些应用程序会要求修饰键被释放.
`n
, `r
和 `r`n
都被转换为一次单独的 Enter, 不像普通模式和原始模式, 转换 `r`n
为两次 Enter. `t
转换为 Tab, 而 `b
转换为 Backspace, 但所有其他字符都是不经转换直接发送的.
与盲从模式类似, 文本模式忽略 SetStoreCapsLockMode(也就是说, 不会改变 CapsLock 的状态), 并且不等待 Win 被释放. 这是因为文本模式通常不依赖于 CapsLock 的状态, 并且不能触发系统 Win+L 热键. 但是, 这仅适用于当 Keys 以 {Text}
或 {Blind}{Text}
开头时.
可以使用 {Blind}
启用盲从模式, 该模式通过禁用通常自动执行的许多操作来使脚本按预期运行, 从而赋予脚本更多控制权. 要启用盲从模式, {Blind}
必须是字符串中的第一个项目. 它具有以下效果:
+s::Send "{Blind}abc"
将发送 ABC 而不是 abc, 因为用户按住了 Shift.^space::Send "{Ctrl up}"
自动推送 Ctrl 按下, 而 ^space::Send "{Blind}{Ctrl up}"
允许 Ctrl 逻辑松开, 即使它物理上是按下的.单词 "Blind" 后面可以用一个或多个修饰符号(!#^+
) 以便在需要时自动释放这些修饰符. 例如, *^a::Send "{Blind^}b"
在按下 Ctrl+Shift+A 时, 将发送 Shift+B 而不是 Ctrl+Shift+B. {Blind!#^+}
可以在需要的时候释放所有的修饰符, 但是会启用盲从模式的其他效果.
在重映射按键时, 盲从模式可以在其内部使用. 例如, 重映射 a::b
会发生这样的情况: 1) 输入 "a" 时会映射为 "b"; 2) 输入大写字母 "A" 时映射为大写字母 "B"; 并且 3) 按下 Ctrl+A 时映射为按下 Ctrl+B. 如果任何修饰符指定为源按键(包括 Shift 如果源按键是大写字母), 则如上所述, 这些修饰符被排除在外. 例如 ^a::b
产生的是正常的 B, 而不是 Ctrl+B.
SendText 或 ControlSendText 不支持 {Blind}
; 请使用 {Blind}{Text}
代替.
SendPlay 不完全支持盲从模式, 尤其是在处理修饰键时(Ctrl, Alt, Shift 和 Win).
下表中列出了可以发送的特殊按键(每个按键名称必须用大括号括起来):
按键名称 | 描述 |
---|---|
{F1} - {F24} | 功能键. 例如: {F12} 表示 F12. |
{!} | ! |
{#} | # |
{+} | + |
{^} | ^ |
{{} | { |
{}} | } |
{Enter} | 主键盘上的 Enter |
{Escape} 或 {Esc} | Esc |
{Space} | Space(这只适用于出现在要发送的字符串的开头或结尾的空格 -- 而在中间的空格是原义的) |
{Tab} | Tab |
{Backspace} 或 {BS} | Backspace |
{Delete} 或 {Del} | Del |
{Insert} 或 {Ins} | Ins |
{Up} | ↑(主键盘上的向上键) |
{Down} | ↓(主键盘上的向下键) |
{Left} | ←(主键盘上的向左键) |
{Right} | →(主键盘上的向右键) |
{Home} | Home(主键盘) |
{End} | End(主键盘) |
{PgUp} | PgUp(主键盘) |
{PgDn} | PgDn(主键盘) |
{CapsLock} | CapsLock(使用 SetCapsLockState 更可靠). 发送 {CapsLock} 之前可能要求 SetStoreCapsLockMode False . |
{ScrollLock} | ScrollLock(另请参阅: SetScrollLockState) |
{NumLock} | NumLock(另请参阅: SetNumLockState) |
{Control} 或 {Ctrl} | Ctrl(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码) |
{LControl} 或 {LCtrl} | 左 Ctrl(技术信息: 发送左边键的虚拟键码而不是中性键) |
{RControl} 或 {RCtrl} | 右 Ctrl |
{Control down} 或 {Ctrl down} | 按住 Ctrl 键直到发送 {Ctrl up}. 要按住左边或右边的键, 请使用 LCtrl 或 RCtrl 替换 Ctrl. |
{Alt} | Alt(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码) |
{LAlt} | 左 Alt(技术信息: 发送左边键的虚拟键码而不是中性键) |
{RAlt} | 右 Alt(或 AltGr, 取决于键盘布局) |
{Alt down} | 按住 Alt 直到发送 {Alt up}. 要按住左边或右边的键, 请使用 LAlt 或 RAlt 替换 Alt. |
{Shift} | Shift(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码) |
{LShift} | 左 Shift(技术信息: 发送左边键的虚拟键码而不是中性键) |
{RShift} | 右 Shift |
{Shift down} | 按住 Shift 直到发送 {Shift up}. 要按住左边或右边的键, 请使用 LShift 或 RShift 替换 Shift. |
{LWin} | 左 Win |
{RWin} | 右 Win |
{LWin down} | 按住左 Win 直到发送 {LWin up} |
{RWin down} | 按住右 Win 直到发送 {RWin up} |
{AppsKey} | Menu (调用右键点击或上下文菜单) |
{Sleep} | Sleep |
{ASC nnnnn} | 发送 Alt+nnnnn 小键盘上的按键组合, 可以用来生成键盘上不存在的特殊字符. 若要从代码页 437 生成可打印的 ASCII 字符或其他字符, , 请指定一个介于 1 和 255 之间的数字. 要生成 ANSI 字符(在大多数语言中的标准), 请指定一个介于 128 和 255 之间的数字, 但需要在数字前加上一个前导零, 例如 {Asc 0133}.. 要生成 Unicode 字符, 请指定一个介于 256 和 65535 之间的数字(不带前导零). 但是, 有些应用程序不支持这种方法. 对于替代方法, 请参阅下面的部分. |
{U+nnnn} | 发送 Unicode 字符, 其中 nnnn 为字符的不包括 0x 前缀的十六进制值. 通常不需要这么做, 因为 Send 和 ControlSend 自动支持 Unicode 文本. 会使用 SendInput() 或 WM_CHAR 来发送字符, 并且当前的发送模式没有效果. 以这种方式发送的字符通常不会触发快捷键或热键. |
{vkXX} |
发送虚拟键为 XX 和扫描码为 YYY 的按键. 例如: XX 和 YYY 的值是十六进制的, 通常可以从主窗口的 View->Key history 菜单项中确定. 另请参阅: 特殊按键 警告: 以这种方式组合 vk 和 sc 仅在 Send 有效. |
{Numpad0} - {Numpad9} | 小键盘上的数字键(与 NumLock 打开时输入的一样). 例如: {Numpad5} 为数字 5. |
{NumpadDot} | .(小键盘上的点)(与 NumLock 打开时输入的一样). |
{NumpadEnter} | 小键盘上的 Enter |
{NumpadMult} | *(小键盘上的乘号) |
{NumpadDiv} | /(小键盘上的除号) |
{NumpadAdd} | +(小键盘上的加号) |
{NumpadSub} | -(小键盘上的减号) |
{NumpadDel} | 小键盘上的 Del(当 NumLock 为 OFF 时, 此键和以下的小键盘按键将被使用) |
{NumpadIns} | 小键盘上的 Ins |
{NumpadClear} | 小键盘上的 Clear 键(在 NumLock 关闭时, 通常为 5). |
{NumpadUp} | 小键盘上的 ↑(向上) |
{NumpadDown} | 小键盘上的 ↓(向下) |
{NumpadLeft} | 小键盘上的 ←(向左) |
{NumpadRight} | 小键盘上的 →(向右) |
{NumpadHome} | 小键盘上的 Home |
{NumpadEnd} | 小键盘上的 End |
{NumpadPgUp} | 小键盘上的 PgUp |
{NumpadPgDn} | 小键盘上的 PgDn |
{Browser_Back} | 浏览器 "后退" 按钮 |
{Browser_Forward} | 浏览器 "前进" 按钮 |
{Browser_Refresh} | 浏览器 "刷新" 按钮 |
{Browser_Stop} | 浏览器 "停止" 按钮 |
{Browser_Search} | 浏览器 "搜索" 按钮 |
{Browser_Favorites} | 浏览器 "收藏" 按钮 |
{Browser_Home} | 启动浏览器并打开主页 |
{Volume_Mute} | 主音量静音/取消静音. 通常相当于 SoundSetMute -1 . |
{Volume_Down} | 减小主音量. 通常相当于 SoundSetVolume -5 . |
{Volume_Up} | 增加主音量. 通常相当于 SoundSetVolume "+5" . |
{Media_Next} | 在媒体播放器中播放下一曲目 |
{Media_Prev} | 在媒体播放器中播放前一曲目 |
{Media_Stop} | 停止媒体播放器 |
{Media_Play_Pause} | 播放/暂停媒体播放器 |
{Launch_Mail} | 启动电子邮件程序 |
{Launch_Media} | 启动媒体播放器 |
{Launch_App1} | 启动用户程序 1 |
{Launch_App2} | 启动用户程序 2 |
{PrintScreen} | PrtScr |
{CtrlBreak} | Ctrl+Pause |
{Pause} | Pause |
{Click [Options]} | Send 鼠标点击使用的选项与 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 决定.
LButton 和 RButton 分别对应鼠标的主按钮和次按钮. 通常鼠标的主按钮(LButton) 在左边, 但是用户可以通过系统设置来交换按钮. |
{Blind} | 启用盲从模式, 通过禁用一些通常会自动完成的事情, 让脚本有了更多的控制权, 从而使事情一般都能正常工作. {Blind} 必须出现在字符串的开头. |
{Raw} | 启用原始模式, 这将导致以下字符按原义解释: ^+!#{} . 虽然 {Raw} 不需要出现在字符串的开头, 但一旦指定, 它将在字符串的其余部分保持有效. |
{Text} | 启用文本模式, 它发送的是字符流而不是按键. 与原始模式一样, 文本模式会使以下字符按原义解释: ^+!#{} . 虽然 {Text} 不需要出现在字符串的开头, 但一旦指定, 它将在字符串的其余部分保持有效. |
重复键击: 用大括号括起按键名称和重复次数. 例如:
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).
DownTemp 告诉后续的发送, 该键不是永久按下的, 只要有按键需要就可以释放. 例如, 在发送 Send "{Control DownTemp}"
之后, 再 Send "a"
将产生一个正常的 A, 而不是 Ctrl+A. 任何使用 Send 的方法都有可能永久地释放修饰键, 所以 DownTemp 并不是重映射修饰键的理想选择.
DownR(其中 "R" 表示重映射, 这是它的主要用途) 告诉后续的发送, 如果该键被自动释放, 则应在发送结束后再次按下. 例如, Send "{Control DownR}"
后面跟着 Send "a"
会产生一个正常的 A, 而不是 Ctrl+A, 但会让 Ctrl 处于被按下的状态, 以便用于键盘快捷键. 换句话说, DownR 有类似于物理按下按键的效果.
如果某个字符与当前键盘布局上的虚拟键不一致, 则不能 "按下" 或 "释放". 例如, Send "{μ up}"
对大多数键盘布局没有效果, 而 Send "{μ down}"
等同于 Send "μ"
.
字符 vs. 按键: 默认情况下, 先将字符转换为按键来发送字符. 如果这种转换是不可能的(即, 如果当前的键盘布局不包含产生该字符的键或键组合), 则通过以下回退方法之一来发送字符:
注意: 使用上述方法发送字符通常不会触发键盘快捷键或热键.
对于 a-z 或 A-Z(纯 ASCII 字母) 范围内的字符, 每个当前键盘布局中不存在的字符可以作为字符或相应的虚拟键码(vk41-vk5A) 发送:
Send "{Raw}Regards"
发送预期的文本, 即使按住 R(vk52) 产生其他一些字符(如 к 在俄语键盘). 在这种情况下, {Raw}
可以省略, 除非一个修饰键被前一个 Send 所实现.^c
和 {Ctrl down}c{Ctrl up}
激活标准的 Ctrl+C 快捷键, 而 {c}
等同于 {vk43}
.如果字母存在于当前的键盘布局中, 那么它总是以布局与该字母相关联的键码发送(除非使用了文本模式, 在这种情况下, 该字符将通过其他方式发送). 换句话说, 上面的部分只适用于非拉丁语系的布局, 如俄语.
修饰键状态: 当 Send 需要改变 Win 或 Alt 修饰键的状态时(比如用户按住其中一个键), 它可能会注入额外的按键(默认为 Ctrl) 来阻止开始菜单或窗口菜单的出现. 有关详情, 请参阅 A_MenuMaskKey.
BlockInput 对比 SendInput/SendPlay: 尽管 BlockInput 函数可以用来防止用户物理输入的任何按键破坏模拟按键的流, 但通常最好使用 SendInput 或 SendPlay 这样按键和鼠标点击就不会中断. 这是因为与 BlockInput 不同的是, SendInput/Play 不会在发送过程中丢弃用户输入的内容; 相反, 这样的按键会被缓冲并在之后发送.
当发送大量的按键时, 可以使用延续片段来提高可读性和可维护性.
由于操作系统不允许模拟 Ctrl+Alt+Del 组合, 所以类似 Send "^!{Delete}"
这样的操作是没有效果的.
当活动窗口以管理身份运行而当前脚本不是时, Send 可能没有效果. 这是由于一种叫做用户界面特权隔离的安全机制造成的.
一般情况下, SendInput 是发送按键和鼠标点击的首选方法, 因为它的速度和可靠性都很高. 在大多数情况下, SendInput 几乎是瞬间完成的, 即使是发送长字符串时也是如此. 由于 SendInput 的速度如此之快, 它的可靠性也更高, 因为这样其他一些窗口更没有机会出乎意料地弹出并打断按键. 用户在 SendInput 过程中输入的任何东西都会被推迟到之后再进行, 从而进一步提高了可靠性.
与其他发送模式不同, 操作系统限制 SendInput 每次只能发送大约 5000 个字符(此限制可能因操作系统版本和性能设置而有所不同). 超过此限制的字符和事件不会被发送.
注意: SendInput 会忽略 SetKeyDelay, 因为在这种发送模式中操作系统不支持延迟. 但是, 在后面描述的情况中, 当 SendInput 恢复到 SendEvent 时, 它会使用 SetKeyDelay -1, 0
(但如果 SendEvent 的按键延迟为 -1,-1
时, 则使用 -1,-1
). 当 SendInput 恢复为 SendPlay 时, 它使用 SendPlay 的按键延迟.
如果脚本安装了底层键盘钩子, SendInput 会在执行之前自动卸载它, 并在执行后重新安装. 因此, SendInput 通常不能触发脚本自己的钩子热键或 InputHooks. 之所以暂时卸载钩子, 是因为它的存在会使 SendInput 的所有优势失效, 使其不如 SendPlay 和 SendEvent. 然而, 这只能对脚本自己的钩子执行, 如果检测到外部钩子, 则不会执行, 如下所述.
当 SendInput 使用像 {Click} 这样的方法发送鼠标点击, 并且 CoordMode "Mouse", "Window"
或 CoordMode "Mouse", "Client"
有效时(默认的), 则每次点击都会相对于发送开始时的那个活动窗口. 因此, 如果 SendInput 有意地激活另一个窗口(通过类似 alt-tab 的方法), 那么这个命令中后续点击的坐标将变成错误的, 因为它们仍然相对于原来的活动窗口而不是新的.
警告: 如果启用了 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"
将显示开始菜单的运行对话框.
SendMode, SetKeyDelay, SetStoreCapsLockMode, 转义序列(例 `n), ControlSend, BlockInput, 热字串, WinActivate