autoit⼊门教程⼩结
作者: yonken
据我了解需要编写AutoHotkey/AutoIt脚本来实现⾃动化操作的⽤户很多都是⽹管,其它则可能是⼀些个⼈⽤户,他们⼀般都具有相当的技术⽔平,⽽且都希望能借助脚本来完成某些以往需要⼈⼯操作的重复性劳动,但限于语⾔条件上的限制可能对官⽅的帮助⽂档有较难理解之处。为⽅便读者,我将从最简单的说起,每个⽰例尽可能同时给出相应的AHK和AU3版本代码。本⽂将尽可能⽤较通俗的语⾔描述,但并不打算讲解语法基础,所以不⼀定适合新⼿阅读。
⽂中涉及到的AHK/AU3版本:
AutoHotkey
1.0.44 .08
AutoIt
3.1.1
⼀、关于脚本
1、什么是脚本?
这是个⾮常“流⾏”的术语了,通俗⽽⾔脚本(Script)⼀般都是指根据某种语法规则编写的具有特定格式的⽂本⽂件。可能⼤家已经听说过很多种脚本:VBScript、JScript、PHP、ASP、JSP、CGI、CS脚本,甚⾄游戏外挂脚本。
这些脚本⽂件都是可执⾏⽂件,可执⾏相应的操作。
AHK 脚本⽂件扩展名:*.ahk
AU3 脚本⽂件扩展名:*.au3
2、脚本和程序的不同?
严格来说,所谓“程序”就是指以各种编程语⾔(⽐如说C/C++/C#/Delphi)编写、由编译器编译好后的⼆进制⽂件,⼀般就是机器代码,可由系统执⾏。⽽脚本则是只是些纯⽂本⽂件,包含了各种定义好的命令,这⼀点很像批处理⽂件。这样,我们得出⼀个简单的结论,那就是⽤户⼀般⽆法获得“程序”的源代码,我们只能进⾏反汇编把它逆向还原为汇编语⾔代码(或其它),当然,也有些“程序” 是可以获得源代码的(⽐如Java);脚本则是⽤户可直接查看的代码⽂件,⽽AHK/AU3则提供了把脚本⽂件“转换”成exe⽂件的⽅法。
3、脚本如何运⾏?
脚本是“解释性”的语⾔,它的运⾏依赖⼀个“解释器”,由这个解释器来“翻译并解释”脚本的每条命令(或者说代码),然后执⾏相应操作。如果不严格定义的话,HTML和Java都可以认为是解释性语⾔。AHK/AU3的主程序(分别是和)就是它们的“解释器”,上⾯提到脚本可“转换”成可脱离相应的解释器⽽独⽴运⾏的exe可执⾏⽂件,⽽我们还可以使⽤相应的⼯具把它们“还原”成脚本⽂件,由此我们完全可以这么理解:脚本代码是被“压缩”到这个exe⽂件中,解释器也是在⾥⾯,在运⾏exe时实际上是先“解压”脚本代码然后运⾏解释器并解释该脚本。
4、如何创建脚本?
使⽤资源管理器的右键菜单即可创建相应脚本⽂件,或者新建⼀个⽂本⽂件后改扩展名即可。
5、稍微介绍⼀点语法规则?
A)对AHK⽽⾔,每个内建的功能都是以“命令”的形式提供:
Command, param1, param2,…
⽽AU3则以“函数”的形式提供:
Function(param1, param2, …)
命令或函数中被符号“[”和“]”围住的参数是可选参数,表⽰在使⽤这些命令或函数时可省略它们(不给出具体数值)。
若某个参数含有空格,则最好使⽤双引号围住该参数。
B)解释器⾃上⽽下(从第⼀⾏到最后⼀⾏)“解释”脚本的每⾏语句,除⾮遇到“Return”、“Goto”、“Gosub”、“Exit”等语句、函数、热键或其它能使脚本“跳”到某个标识符的条件成⽴。
C)关键字和标识符(包括变量名、命令名、函数名等)都不区分⼤⼩写。
⼆、运⾏程序或打开⽂件
1、运⾏程序
Run t命令或者函数⽤来运⾏外部可执⾏⽂件,AHK还可利⽤它来直接打开⽂件。
AHK:
Run, ⽬标⽂件 [, ⼯作⽬录, Max|Min|Hide|UseErrorLevel, 输出PID变量]
AU3:
Run ( "⽂件名" [, "⼯作⽬录" [, 标志]] )
【⽰例 2.1.1 】
AHK:
Run,
AU3:
Run("")
上⾯的⽰例中都没有给出程序“”的路径,为什么仍能执⾏?这是因为它们都会⾃动在脚本所在⽬录下搜寻⽬标⽂
件,如有则运⾏,否则就到系统⽂件夹(%PATH%)中搜寻。
注意:
A)某些程序必须给定“⼯作⽬录”才能成功运⾏!
B)给出完整的⽂件路径有助于轻微提⾼程序的可靠性。
C)AHK的Run命令可以⽤来运⾏程序和直接打开⽂件,⽽AU3的Run函数则只能⽤来运⾏程序(可执⾏⽂件)或传递参数让某个程序打开⽬标⽂件。
当然,运⾏程序的功能还不仅仅是这么简单,我们还可以指定运⾏程序的初始状态,⽐如让运⾏的记事本窗⼝以最⼤化状态显⽰(或者最⼩化、隐藏):
【⽰例 2.1.2 】
AHK:
Run, , , Max
AU3:
Run("", "", @SW_MAXIMIZE)
2、打开⽂件
前⾯已经提到,AHK的Run命令可以直接打开⽂件,⽽AU3的Run函数则只能⽤来运⾏程序,因此在打开⽂件的⽅式上有点不同:AHK脚本中可直接给出⽬标⽂件,⽽AHK将⾃动运⾏该⽂件的关联程序来打开它;⽽AU3则必须由⽤户⾃⼰传递参数让某个程序打开⽬标⽂件。
【⽰例 2.2.1 】
AHK:
Run,
Run,
AU3:
Run(" ")
3、以命令⾏形式运⾏程序
可以考虑运⾏系统的命令⾏解释器(/command),然后指定要执⾏的命令并传递参数。
假设我们要执⾏命令“dir C:\WINDOWS\system 32” ,⽤以列出指定⽬录的所有⽂件及⼦⽬录。
【⽰例 2.3.1 】
AHK:
Run, %ComSpec% /k dir C:\WINDOWS\system32
AU3:
Run(@ComSpec & " /k dir C:\WINDOWS\system32")
注意:
A)ComSpec是脚本内建的⽤以指⽰命令⾏解释器位置的变量或宏。
B)/k 参数表⽰“执⾏字符串指定的命令但保留”,若改为 /c 则表⽰“执⾏字符串指定的命令然后终断”。对此⽐较直观的解释
是 /k 将在执⾏完命令后保留命令提⽰窗⼝,⽽ /c 则将在执⾏完命令之后关闭命令提⽰窗⼝。
C)符号“&”是AU3定义的字符串连接符。
4、特殊应⽤
A)打开⽹页
【⽰例 2.4.1 】
AHK:
Run, www.autohotkey
Run, %A_ProgramFiles%\Internet Explorer\IEXPLORE.EXE www.autohotkey
AU3:
Run(@ProgramFilesDir & "\Internet Explorer\IEXPLORE.EXE www.autohotkey")
B)打开特殊⽂件夹
系统的某些特殊⽂件夹被定义了相应的CLSID(请查看帮助⽂档),我们可利⽤它来打开相应的⽂件夹,⽐如打开回收站:【⽰例 2.4.2 】
AHK:
Run ::{645ff040-5081-101b -9f 08-00aa 002f 954e}
AU3:
不适⽤!
C)运⾏控制⾯板⼯具
微软已经为我们提供了通过命令⾏打开控制⾯板某个⼯具或项⽬的⽅式,⽐如打开系统属性窗⼝:
【⽰例 2.4.3 】
AHK:
Run control sysdm.cpl
AU3:
Run("control sysdm.cpl")
关于访问控制⾯板项⽬的详细介绍请查看此⽂:⽂章地址。
D)指定搜索位置并打开搜索窗⼝
假设我们要打开⼀个搜索窗⼝,⽽且要指定搜索位置,⽐如C:\:
【⽰例 2.4.4 】
AHK:
怎么显示文件的扩展名Run, find C:\
AU3:
不适⽤!
E)显⽰指定⽂件的属性窗⼝
假设我们要打开⽂件“”的属性窗⼝,则使⽤关键字properties 然后接上⽬标⽂件即可:
【⽰例 2.4.5 】
AHK:
Run,
AU3:
不适⽤!
注意:AHK在退出前将⾃动关闭打开的属性窗⼝!
F)⽤“资源管理器”打开指定⽂件夹
我们知道使⽤Run, explorer C: 或Run("explorer C:") 即可打开指定的⽂件夹,可是有时候我们需要在资源管理器中打开它,这时可使⽤关键字 explore:
【⽰例 2.4.6 】
AHK:
Run, explore C:
AU3:
run(" /e,C:\")
G)打印指定⽂件
要打印指定⽂件,可使⽤关键字 print:
【⽰例 2.4.7 】
AHK:
Run,
AU3:
不适⽤!
F)⽤“资源管理器”打开指定⽂件夹
我们知道使⽤Run, explorer C: 或Run("explorer C:") 即可打开指定的⽂件夹,可是有时候我们需要在资源管理器中打开它,这时可使⽤关键字 explore:
【⽰例 2.4.6 】
AHK:
Run, explore C:
AU3:
不适⽤!
run(" /e,d:\")
这样就可以做到你说的打开树状⽂件了
注意:窗⼝标题和窗⼝⽂本参数总是对⼤⼩写敏感的。
1、等待窗⼝系列命令/函数
AHK和AU3都提供了⽤法类似的⼀组窗⼝等待命令/函数:WinWait/WinWaitActive/WinWaitClose。
它们分别⽤于等待窗⼝出现、等待窗⼝被激活、等待窗⼝被关闭。由于这些命令/函数的参数类似,现仅以WinWait为例说明。AHK:
WinWait [, 窗⼝标题, 窗⼝⽂本, 超时时间, 排除标题, 排除⽂本]
AU3:
WinWait ( "窗⼝标题" [, "窗⼝⽂本" [, 超时时间]] )
WinWait 的作⽤是在⽬标窗⼝出现之前不再执⾏后⾯的所有语句。
假设我们要运⾏记事本程序,并在其窗⼝出现时提⽰⽤户:
【⽰例 3.1.1 】
AHK:
Run Notepad
WinWait, ⽆标题 - 记事本
MsgBox 记事本窗⼝已被打开!
AU3:
Run("Notepad")
WinWait("⽆标题 - 记事本")
MsgBox(0, "", "记事本窗⼝已被打开!")
2、激活窗⼝相关命令/函数
让⽬标窗⼝成为活动窗⼝的办法就是激活它,可⽤的命令/函数是WinActivate:
AHK:
WinActivate [,窗⼝标题, 窗⼝⽂本, 排除标题, 排除⽂本]
AU3:
WinActivate ( "窗⼝标题" [, "窗⼝⽂本"] )
3、关闭窗⼝
关闭窗⼝有两种⽅式,⼀种是正常的关闭窗⼝(WinClose),另⼀种则是强⾏关闭窗⼝(WinKill):
AHK:
WinClose/WinKill [,窗⼝标题, 窗⼝⽂本, 超时时间,, 排除标题, 排除⽂本]
AU3:
WinClose/WinKill ( "窗⼝标题" [, "窗⼝⽂本"] )
现在我们已经可以实现⼀个⽐较简单的功能了,⽐如我们可以打开系统属性窗⼝并等待其出现,窗⼝出现后激活它,接着等待3秒再关闭它:
【⽰例 3.1.2 】
AHK:
Run, Sysdm.cpl
WinWait, 系统属性
WinActivate, 系统属性
WinWaitActive, 系统属性
Sleep, 3000
WinClose, 系统属性
WinWaitClose, 系统属性
AU3:
Run("Control Sysdm.cpl")
WinWait("系统属性")
WinActivate("系统属性")
WinWaitActive("系统属性")
Sleep(3000)
WinClose("系统属性")
WinWaitClose("系统属性")
建议:如果程序中频繁地出现要⽤到这些窗⼝标题的地⽅,会带来⼀个问题:脚本的可读性,也许你会想,这不是很直观吗?可问题是如果这个重复出现的窗⼝标题是个很长的字符串呢?这将严重影响整个代码的排版美观。⽽且我们也⽆从了解这些窗⼝标题的“来头”,不知道这个窗⼝标题究竟是怎么来的。⽽如果我们定义⼀个变量(假设变量名是“AppWindow1”)保存这个窗⼝标题,我们就能在命令/
函数中⽤变量来表⽰它,这样就达到了让代码⽤意更清晰⼀点的⽬的。另外,就算⽬标软件因某些原因(⽐如升级)⽽改变了它的窗⼝标题,我们也能很⽅便地作出修改。
4、更准确的标识窗⼝的⽅法(主要针对AHK脚本)
程序在运⾏时起码会有⼀个进程,如果能获得这个进程ID就能在⼀定程度上保证对窗⼝的准确标识。另外,每个窗⼝都有定义窗⼝类名(Class,⽐如说记事本窗⼝的类名就是Notepad),所以我们可以以此排除与⽬标窗⼝不同的其它窗⼝类。其实,我们还有⼀个更准确的⽅法:
每个窗⼝(包括控件在内)都被Windows指派了⼀个可区别于其它窗⼝的唯⼀的标识符(ID),我们称之为窗⼝句柄(HWND)。
直接给定窗⼝标题来表⽰窗⼝的⼀个缺点就是⽆法保证在脚本运⾏的过程中始终以该窗⼝为操作⽬标,因为在这个过程中很有可能会有其它“同名”窗⼝(或者说满⾜匹配条件的窗⼝)出现,⽽如果我们使⽤这个标识符来表⽰窗⼝⾃然就能保证命令/函数的操作窗⼝总是同⼀个窗⼝了。
我们先来了解⼀下获得窗⼝句柄的命令/函数:
AHK:
WinGet[, 输出变量, ID, 窗⼝标题, 窗⼝⽂本, 排除标题, 排除⽂本]
AU3:
WinGetHandle ( "窗⼝标题" [, "窗⼝⽂本"] )
其中WinGet获得的窗⼝ID将通过“输出变量”返回,⽽WinGetHandle的返回值就是获得的窗⼝ID。
我们在进⾏⾃动化操作时是要先运⾏某个程序,如何获得这个程序成功运⾏后显⽰的窗⼝句柄?⼀个⽐较保险的办法是先获得这个程序的进程ID,然后根据这个进程ID获得它的窗⼝句柄,AHK⽀持使⽤进程ID作为窗⼝标题使⽤;但AU3不⽀持这样使⽤,只能先获得该窗⼝的类名再根据该类名来获得窗⼝句柄(不够保险):
【⽰例 3.1.3 】
AHK:
Run, NotePad, , , ThisPID
WinWait, ahk_pid %ThisPID%
;这⾥的ahk_pid表明跟在后⾯的变量是进程ID
WinGet, ThisID, ID, ahk_pid %ThisPID%
;ThisID将保存获得的窗⼝句柄
AU3:
Opt("WinTitleMatchMode", 4)
Run("Notepad")
$handle = WinGetHandle("classname=Notepad")
现在暂且先忘记了AU3吧,因为它的窗⼝函数⼀般都不⽀持使⽤窗⼝句柄作为(窗⼝标题)参数。
⾄于如何在AHK中使⽤窗⼝句柄,简单的说,凡是有“窗⼝标题”参数的命令就可以⽤窗⼝句柄来代替,⽐如:
【⽰例 3.1.4 】
AHK:
Run, Notepad, , , ThisPID
;先获得运⾏的记事本程序的进程ID
WinWait, ⽆标题 - 记事本 ahk_pid %ThisPID%
;等待该进程窗⼝的出现
WinGet, ThisHWND, ID, ⽆标题 - 记事本 ahk_pid %ThisPID%
;获得窗⼝句柄
WinActivate, ahk_id %ThisHWND%
;这⾥的ahk_id表明跟在后⾯的变量是窗⼝句柄
WinWaitActive, ahk_id %ThisHWND%
Sleep, 3000
WinClose, ahk_id %ThisHWND%
WinWaitClose, ahk_id %ThisHWND%
1、模拟⿏标点击(按钮等)控件
既然是模拟⽤户操作,⾃然就包括了模拟⿏标点击在内。
适⽤命令/函数:Click/MouseClick/ControlClick
其中Click/MouseClick⽤来模拟⽤户的物理操作(点击),把⿏标点击事件发送到指定坐标位置(相对当前窗⼝或绝对位置)上,但这种⽅法并不能保证100%的准确性,屏幕分辨率、⽤户⼲扰和系统环境等都会影响到它们的执⾏结果,⽽ControlClick则直接把⿏标点击事件发送到⽬标窗⼝的⽬标控件上,因⽽更准确,⼀般我们不考虑使⽤坐标位置⽅式的点击,下⾯仅以ControlClick为例说明:
AHK:
ControlClick [, ⽬标控件或坐标位置, 窗⼝标题, 窗⼝⽂本, ⿏标按钮, 点击次数, 选项,排除标题, 排除⽂本]
AU3:
ControlClick ( "窗⼝标题", "窗⼝⽂本", 控件ID [, 按钮] [, 点击次数]] )
对AHK⽽⾔,“⽬标控件”参数是指要点击的控件的类别名(ClassNN)或控件⽂本,另外还可以使⽤控件句柄(若⽤的是控件句柄则第⼀个参数需留空,并在第⼆个参数中使⽤ahk_id %控件句柄%)。
Q:⽤什么⼯具来获得⽬标控件的这些信息呢?
A:AHK⽤户请使⽤ AutoIt3 Window Spy,AU3⽤户则请使⽤AutoIt Window Info,你可以在相应的开始菜单项⽬⾥到它们,或者到安装⽬录下寻。
Q:如何使⽤这两个⼯具?