AutoHotKey初学指南

最开始的时候, 同学在工作中需要为服务器安装软件, 但多台服务器的重复工作让他想寻找一种自动化的方式, 于是拜托我找一找. 但这方面我没有研究, 随便找了下, 也就是基于打包软件的命令行安装, 以及类似AutoHotKey这样的自动化软件. 如果没听过AutoHotKey, 你可以理解为按键精灵之类的.

第一种方式, 由于安装文件的打包软件有很多种, 像NullsoftInstallShieldAdvanced Installer等, 我自己没有开发过像样的Windows程序, 这方面不了解. 查资料的结果是不同打包形式需要不同的命令和参数, 有得似乎并不提供静默安装的方式. 另外, 得针对不同软件, 辨别打包形式, 也挺麻烦.

至于第二种, 熟悉Linux平台的应该都习惯于使用脚本做一些自动化操作. 这里的脚本包括shell, python, ruby等. 所以, 基于学习另一种语言的想法, 便看了AutoHotKey的初学指南.

注意: 此处并不是原文翻译, 只是自学笔记和感受, 主观成份很多.


AutoHotKey(以下简称AHK)是Windows平台下一款免费开源的自动化软件, 方便用户处理重复性的任务. 它是一种脚本语言, 最开始只用于定义热键(hotkey)和相应的动作.

快速开始

在官网https://autohotkey.com/下载软件并安装. 任意目录右击新建Autohotkey script, 追加^w::MsgBox, hello, world文本, 保存并双击脚本运行. 在任务栏右下脚会出现AutoHotKey的运行图标. 此时, 按键Ctrl+w会弹出对话框, 显示hello, world, 说明软件工作正常.

追加文本有这样的形式, hotkey::action. 此处, ^表示Ctrl键, 如果一定要区别左右, 可以使用<^>^的形式. 还有!表示Alt键, #表示Win键, +表示Shift键, 且都可以使用<>前缀表示左右键. ^w表示快捷键Ctrl+w, ^!w表示快捷键Ctrl+Alt+w, 依此类推. 而动作部分是一个命令MsgBox, 表示弹出对话框, 并显示文本. 可以有更多的参数, 以自定义标题栏文本, 选择按钮(如yes/no/cancel还是drop/save/ignore).

所谓的组合键, 字面意思是同时按下多个键, 但如果你的多个键都是正常键, 即没有`Ctrl`, `Alt`, `Shift`, `Win`键的话, 需要`&`来组合. 如同时按`a`和`b`, 表示为`a & b`. 另外, 如果热键只有`Ctrl`单键, 则需要用`Ctrl`来表示, 左右为`LCtrl`和`RCtrl`, 不区分大小写. 其余键类同.

此处, 因为动作只有一个, 因此写到::后即可, 多个动作从第二行起, 每行一个动作, 最后写上Return表示此热键定义的动作完毕, 下面的内容属于另一个热键的.

除了定义热键外, AHK另一个常用法是文本替换, 或者说热字串(hotstring). 如::hw::hello, world. 重载入后, 在任意输入框, 包括所有的文本编辑器, 浏览器地址栏, 百度搜索框等, 当键入hw后, 任意结束符EndChar都会触发文本替换. 此处的结束符, 可能理解为非数字字母. 本质上, 当键入结束符, 由AHK发出退格键N次再键入入替换文本.

注意, 每添加一个新的热键或热字串, 都需要重新载入脚本. 可在右下脚的运行图标上右击, 选择Reload this script. 或者可以自定义热键来重载入脚本.

hotkey::action  ;1, 单行定义
hotkey::        ;2, 多行定义    action1    action2    ...Return
::hotstring::text  ;3, 热字串, 文本替换
::hotstring::      ;4, 热字串, 动作触发
   action
Return

虽然我这里区分了大小写, 但事实上AHK并不区分大小写, 但仍然推荐驼峰写法以方便辨认.

通过这种方式定义的热键或热字串都是全局性的, 如果想定义针对特定窗口的热键或热字串, 可以用如下形式

#IfWinActive Untiled - Notepad  ;标题栏文本#space::    MsgBox You pressed Win+Spacebar in notepad.Return#IfWinActive

此处在无标题记事本中创建了热键Win+space.

AHK还提供了简单的条件语句

if (var = 5) {  ; equal?    msgbox, var equals %var%} else {    MsgBox, var not equals %var%}

以上4种形式, 就基本是AHK的主要内容了.

分点细讲

AHK最主要的部分是热键, 函数, 和命令. 热键方面, 要知道你想要的热键如何表示. 函数和命令则是需要查表和记忆. 其余还有变量, 各种语句等.

函数和命令是AHK最奇怪的部分. 命令没有返回值, 函数有; 命令行参数文本默认为字串, 函数参数的字串必须'包围; 命令参数不能嵌套命令, 而函数参数可以是另一个函数的返回值; 命令参数文本中的+!#^被解析为特殊热键, 需要{}包围来表示原符号, 而函数参数中的字串不需要; 命令的参数中变量以%包围, 函数不需要; 命令参数中数学表达式并不运算, 函数会.

以上的不同, 并不是针对函数和命令的参数, 在其他方面也适用. 我一般将命令参数表现出来的特性理解成文本, 而函数参数表现出来的特性理解成表达式. 以下会提到在赋值语句中的差异. 其实在条件语句中, 当有()时, 适用表达式, 而没有()时, 适用文本. 但即使在文本中, 也只有在操作符如=<>右边才需要%包围变量.

这些差异大部分时候让我觉得很奇怪, 不明白语言为什么如此设计. 我相信这对任何一个学习过通用编程语言的人来说, 都是不可接受的. 但考虑到AHK其实并不是作为脚本语言被精心设计, 而是在autoit软件的基础上扩展起来的. 这是自己的理解, 我对AHK的历史以及开发记录并不了解.

变量

使用变量并不需要类型声明, 这点类似动态语言.

var = textvar := expression

上面说的文本和表达式的差异在此处也适用. 如num = 5*3, 实际上, num并不是15, 而是字串5*3. 此处数学表达式不运算, 而:=则会. 另外, var1=var2并不是将var2的内容给var1, 而是将字串var2var1. 需要var1=%var2%来达到目的. 而var1:=var2则可以.
其实差异还是挺多的, 所以我一直认为这里的语法设计的太冗余了. 建议大家可以的话, 尽量使用:=.

命令

因为命令比较经常使用, 先介绍经常使用的命令. 再声明一遍, 命令名不区分大小写.

cmd, arg1[, arg2, arg3...], 这是命令的一般形式, []内的参数表示可以省略. 如果只想省略中间的某个参数, 用,,连续两个,来将此位置的参数空过.

注意上面提到的, 在命令参数中, 有特殊的注意事项.

参数使用变量用%包围, 文本和数字无需'包围, 参数不进行数字运算. 一行一条命令.

Send, text: 发送文本, 本质上是发送敲击的键. 对于数字字母就是对应的符号, 而+!#^则是对应的热键, 请以{}包围. 另外, 还有些特殊键, 如回车{enter}, 删除{del},  大写{CapsLock}等.

Run, program: 运行程序, AHK会在%path%中查找. 如Run, NotePad.exe, 其中后缀可省略. 除了程序, 也可以直接打开网页run, www.baidu.com会调用默认浏览器打开百度首页. 也可以打开目录, 如run, %A_MyDocuments将打开我的文档. 此处的%A_MyDocumentsAHK预定义变量.

WinActivate, title_text: 激活指定标题栏的窗口, 注意操作系统环境不同, 标题栏文本的语言也不同. 如打开记事本, 在英文环境下, 标题栏文本是Untitled - notepad, 中文环境下是无标题 - 记事本. 我想, 这里是AHK唯一区分大小写的地方了吧.

WinWaitActive, title_text: 等待指定窗口的激活, 往往同上一起使用, 以确保接下来的命令运行在正确的窗口中.

sleep, num, 停止毫秒

MsgBox, text: 显示对话窗口, 跟文本参数, 只有确定按键.

MsgBox [, options, title, text, timeout]: 单独一个msgbox会提示press ok to continue, 选项显示不同的按钮, 如4yes/no或1ok/cancel,2abort/retry/ignore,3yes/no/cancel等.

InputBox, output_var, title_text, question_text, 以窗口形式获取用户输入

IfMsgBox, Yes/No: 如果对话框点击确定或否, 或者依据选项的不同输入, 来决定下一步

函数

函数一般有这样的形式, var:=func(arg1, arg2, ...).

变量直接用, 字串以'包围, 参数进行数字运算, 函数可嵌套, 有返回值.

SubStr(string, num), 返回从num位置的字串, 1索引

FileExist(path), 文件存在判断

特殊按键

  • {f1}-{f12}

  • {enter/space/esc/tab}

  • {bs/del/ins}

  • {up/down/left/right}

  • {home/end/pgup/pgdn}

  • {capslock/scrolllock/numlock}

  • {ctrl/lctrl/rctrl down/up}, alt, shift, win

  • {+!^#{}}, 仅表示+, !, ^, #, {, }

  • {numpad0-9}, {numpaddot/enter/mult/div/add/sub}数字键盘的键, 按下numlock键时

  • {numpadup/down/left/right/home/end/pgup/pgdn/del/ins/clear}数字键盘的控制键, numlock未按下时

  • {browser_back/forward/refresh/stop/search/favorites/home}, 浏览器的按键

  • {volume_mute/down/up音量键

  • {media_next/prev/stop/play_pause}媒体控制键

预定义变量

%包围, 如%A_WorkingDir%.

脚本属性:

  • 1, 2, 3, 脚本的命令行参数, 0表示参数数目

  • A_ScriptDir, A_ScriptName, A_ScriptFullPath, A_ScriptHwnd运行脚本的目录,文件名,全路径,主窗口句柄.

  • A_LineFile, A_LineNumber, A_ThisFunc, A_ThisLabel表示当前运行命令的文件,行号,函数,标号, 用于错误处理

  • A_AhkVersion, A_AhkPath本程序的版本和路径

  • A_IsUnicode, A_IsCompiled, A_ExitReason是否是unicode, 是否编译, 退出原因

对象

创建对象: (数组或列表, 字典或哈希, 在不同语言中叫法不同)

MyObject := ['one', 'two', 'three', 17]  ; 字面量创建
banana := {'Shape': 'Elongated', 'Color': 'Yellow'}
MyObject := Array('one', 'two', 'three', 17)  ; 函数创建
Banana := Object('Shape', 'Elongated', 'Color', 'Yellow')

添加新元素或改变原键值:

Banana.Consistency := 'Mushy'   Banana['Pickled'] := True  ;两种方式索引, `.`和`[]`操作符 MyObject.NewKey := 'Shiny'  ;给数组添加键值对 MyObject.InsertAt(Index, Value1, Value2, Value3, ...)  ;多元素插入MyObject.Push(Value1, Value2, Value3, ...)  ;追加元素

移除键值:

MyObject.NewKey := ''  ; 移除值
RemovedValue := MyObject.Delete(AnyKey)  ; 移除键
NumberOfRemovedKeys := MyObject.Delete(FirstKey, LastKey)
MyObject.Pop()  ; 弹出尾元素
RemovedValue := MyObject.RemoveAt(Index)  ; 移除索引处键
NumberOfRemovedKeys := MyObject.RemoveAt(Index, Length)

这里需要说明的是, ArrayObject是相同的对象, 数组默认的数字索引, 但也可以添加键值对. 则之前的值通过1,2,3索引, 加入的值通过键索引.

对于数组, 第一个元素的索引为1.

另外, 在命令中, 默认的是文本, 似乎不能直接输出MyObject.NewKey, 无论是否以%包围. 变通的方法是赋值给变量, 再将变量以%输出.

(0)

相关推荐