
简介AutoItAU3V3.3.6.1绿色汉化特别版面向需要Windows桌面自动化、批量运维与GUI脚本编写的初学者及中级用户解决重复键鼠点击、窗口控件操作和注册表处理等场景中手工效率低、常规脚本语言难以可靠模拟交互的问题。压缩包共194个文件、约6.44MB以129个au3脚本及API示例为核心辅以properties配置、lua脚本、exe工具、api帮助文件和Scite相关配置另含readme、chm文档与dll组件便于边看示例边改脚本。该版本无需安装即可运行保留Aut2Exe脚本编译能力并附带AutoItX以COM/DLL方式嵌入其他语言。已有871人学习适合想系统掌握模拟键击、鼠标移动、窗口调整、剪贴板与注册表操作并借助现成示例快速搭建自动化小工具的读者。1. 免安装的 AutoIt 脚本环境我把它当成一门 BASIC 方言先用起来上周同事丢过来一个压缩包说里面是 AutoIt V3.3.6.1 绿色汉化版解压就能跑问我能不能把每天重复点十几个窗口、填同一张表单的活干掉。我的判断很直接AutoIt 脚本本来就是 BASIC 的变体If/Then/EndIf、Func/EndFunc这套结构写过 VB6 的人半小时能上手真正难的不是第一行代码而是把脚本从「我这台机器能跑」变成「别人机器也能跑」。绿色版省掉的是安装和路径配置SciTE 编辑器、Au3Info 窗口探测器、Aut2Exe 编译器都塞在同一个目录里解压即可验证要花心思的是窗口标题怎么匹配、控件 ID 怎么抓、权限边界在哪。下面按跑通第一个脚本、语法与控件、文件与进程、排错、进阶验证的顺序拆开讲适合做桌面自动化、批量填单、安装引导的从业者。2. 绿色版目录与第一个脚本从解压到 Aut2Exe 出 exe拿到压缩包先别急着双击 exe。这个版本的核心价值在于组件齐全、路径关系已经理顺先把目录结构看清楚后面写脚本时才知道某个函数该去哪个文件里找。2.1 五个必须认识的组件以及它们的分工解压后一般能看到这么几样东西我按使用频率排文件 / 目录作用什么时候必须用AutoIt3.exe脚本解释器双击 .au3 默认走它调试阶段改一行跑一次Au3Info.exe窗口探测器抓标题、控件 ClassNN、坐标写控件操作前必开Aut2Exe.exe把 .au3 编译成独立 exe要发给别人时SciTE.exe编辑器带语法高亮F5 运行、F7 编译日常写脚本Include\标准库如 Array.au3、GUIConstantsEx.au3用到数组函数、GUI 时才 include解释器和编译器的关系要说清楚.au3 文件双击时由 AutoIt3.exe 逐行解释执行依赖 Include 目录里的库文件编译时 Aut2Exe 把脚本、解释器内核、以及脚本里#include引用到的库函数一起打成一个 exe目标机器不需要装 AutoIt。这就是为什么同一个脚本「解释能跑、编译后报错」——通常是某个 include 在编译时没被正确解析。我的习惯是把整个目录放到D:\Tools\AutoIt3这种纯英文、无空格的路径下。绿色版虽然是免安装但 Aut2Exe 在调用编译器时如果路径里有中文或空格偶尔会翻车编译器直接返回一个看不懂的错误码。这个坑不值当踩一开始就避开。提示绿色版不会自动关联 .au3 文件第一次可以右键「打开方式」手动指向 AutoIt3.exe或者干脆在 SciTE 里打开脚本按 F5省掉关联这一步。2.2 用 Au3Info 抓窗口写出第一个能操作的脚本写脚本前先开 Au3Info.exe。把 Finder Tool那个准星图标拖到目标窗口上看两个页签Window 页的 Title 和 ClassControl 页的 ClassNN 和 Text。ClassNN 就是后面ControlSetText、ControlClick要填的控件标识形如Edit1、Button2。下面这段是能直接跑的完整例子打开记事本、写入两行文字; 标题匹配模式设为 2包含匹配比默认的完全匹配宽容得多 Opt(WinTitleMatchMode, 2) Run(notepad.exe) ; 第三个参数是超时秒数返回窗口句柄0 表示失败 Local $hWnd WinWait([CLASS:Notepad], , 10) If $hWnd 0 Then MsgBox(16, 失败, 10 秒内没等到记事本窗口) Exit 1 EndIf WinActivate($hWnd) WinWaitActive($hWnd, , 5) ; 控件级写入不走键盘模拟不受输入法影响 ControlSetText($hWnd, , Edit1, AutoIt 脚本写入的第一行) ControlSend($hWnd, , Edit1, {ENTER}第二行内容)逻辑说明Run只负责拉起进程不等窗口WinWait才是等待点它的第二个参数是窗口内文本一般留空第三个是超时秒数。返回值是 HWND 句柄后续所有Control*函数都可以直接传句柄比反复传标题字符串稳得多——标题可能随文档名变化句柄在窗口存活期内不变。参数说明WinWait的标题里用[CLASS:Notepad]而不是「无标题 - 记事本」是因为记事本的标题会随打开的文件变类名不变。ControlSetText的第三个参数Edit1就是 Au3Info 里抓到的 ClassNN不是控件上显示的文字。ControlSend里的{ENTER}是 AutoIt 的键码写法和普通字符混排时不用拆成两次调用。2.3 编译成 exeWrapper 指令与 32 位选项编译有两条路Aut2Exe 的图形界面和 SciTE 里按 F7 走 AutoIt3Wrapper。我基本只走后者因为只有 Wrapper 认脚本顶部的编译指令图形界面会全部忽略。; 以下指令只在通过 AutoIt3Wrapper 编译时生效 #AutoIt3Wrapper_Iconapp.ico #AutoIt3Wrapper_OutfileFillFormHelper.exe #AutoIt3Wrapper_UseX64n #AutoIt3Wrapper_Res_Fileversion1.0.0.3 #AutoIt3Wrapper_Res_Description批量填单助手 #include GUIConstantsEx.au3 ; 下面是脚本主体 If Not FileExists(ScriptDir \settings.ini) Then MsgBox(48, 提示, 缺少 settings.ini放在 exe 同目录下再运行) Exit 2 EndIf逻辑说明这几行#AutoIt3Wrapper_*是编译期指令不参与运行。UseX64n强制生成 32 位 exe看起来是退步实际是稳——很多老系统上的老控件在 64 位进程里句柄行为不一致32 位进程反而兼容性更好。Outfile指定输出文件名不写就按脚本名生成。Res_Fileversion和Res_Description会写进 exe 的版本资源出问题时在文件属性里能直接看到版本方便确认对方跑的是不是最新包。参数说明图标文件路径是相对 .au3 脚本所在目录不是相对 exe 输出目录这一点容易搞混。编译产物默认和脚本同目录如果脚本在源码树里最好用Outfile指到一个单独的 dist 目录避免把源码和产物混在一起。3. 语法与控件操作把 BASIC 味道的脚本写成可维护的样子AutoIt 的语法糖不少但坑也多。变量只有一种类型、宏满天飞、控件操作有优先级这三件事想清楚脚本质量会差一个档次。3.1 变量、常量与宏弱类型的边界在哪AutoIt 只有 Variant 一种数据类型字符串和数字靠上下文自动转换。方便是真的方便翻车也是真翻车——12 1得 1312abc 1得 1因为非数字前缀被截断成 0。; 函数外声明全局函数内用 Local Global Const $TIMEOUT 20 Global $g_sLogFile ScriptDir \run.log Local $sUser UserName ; 当前登录用户名 Local $sHost ComputerName ; 计算机名 Local $sDir ScriptDir ; 脚本/exe 所在目录 ; 字符串拼接用 加法用 别混 Local $sMsg 用户: $sUser 主机: $sHost ; 需要确定是数字时显式转换别赌自动转换 Local $iCount Number(12) 1 ; 数组下标从 0 开始StringSplit 返回的 [0] 是元素个数 Local $aParts StringSplit(a|b|c, |) For $i 1 To $aParts[0] ConsoleWrite($aParts[$i] CRLF) Next逻辑说明Const修饰的常量编译期就固定后面误赋值会直接报错比裸写数字好维护。ScriptDir、UserName这类叫宏本质是运行期只读变量不需要声明就能直接用但拼错不会报错只会得到空字符串——这是新手最常见的静默失败来源之一。参数说明StringSplit返回的数组第 0 位存元素数量实际数据从下标 1 开始这个约定跟大多数语言相反遍历时必须从 1 起。Number()转换失败返回 0不会抛异常所以转换前最好用StringIsDigit()判断一下。3.2 控件操作的优先级ControlSend 优于 SendSend 优于 MouseClick这三者的可靠性是递减的血泪经验就一句话能用控件就别用键盘能用键盘就别用鼠标。ControlSend直接把按键消息投递给指定控件不要求窗口在前台不受输入法状态影响Send走当前焦点窗口窗口被遮挡、输入法开着中文、CapsLock 状态不对都可能让输出变成一堆乱码MouseClick依赖屏幕坐标换个分辨率、改个缩放比例就全偏了。; 第一选择控件级点击传句柄 ClassNN ControlClick($hWnd, , Button1) ; 第二选择窗口级按键先把窗口激活并保持 WinActivate($hWnd) WinWaitActive($hWnd, , 5) Send(^s, 1) ; 第二个参数 1 慢速模式每键之间加延迟 ; 第三选择坐标点击坐标必须显式切到窗口客户区 Opt(MouseCoordMode, 2) ; 2 相对当前窗口客户区默认 1 是屏幕坐标 MouseClick(left, 120, 40, 1, 0)逻辑说明ControlClick的第二个参数是窗口内文本通常留空第三个是控件 ClassNN。有些程序尤其是自绘界面的根本没有标准控件Au3Info 抓出来是一片空白这时候只能退回Send或坐标点击并且在脚本里加注释说明「此处依赖坐标界面改版需同步修改」。参数说明Send的第二个参数是模式标志0 是默认快速发送1 是慢速每个字符之间插入延迟。慢速模式对老程序、远程桌面、虚拟机里的输入更友好代价是脚本变慢几十个字符大概多出零点几秒。MouseCoordMode设为 2 后坐标原点变成窗口客户区左上角标题栏和边框不算在内这样窗口移动位置不影响点击。3.3 等待与超时超时值怎么定失败怎么兜WinWait不传第三个参数就是无限等脚本会一直卡在那里看起来像死机。我一般封装一个带超时和激活兜底的等待函数所有脚本共用。; 等待窗口出现并激活失败时返回错误码 Func _WaitWindow($sTitle, $iTimeout 20) Local $h WinWait($sTitle, , $iTimeout) If $h 0 Then Return SetError(1, 0, 0) ; 错误 1窗口没出现 If Not WinWaitActive($h, , 5) Then WinActivate($h) If Not WinWaitActive($h, , 5) Then Return SetError(2, 0, $h) ; 错误 2窗口在但激活不了 EndIf EndIf Return $h EndFunc逻辑说明WinWait只要窗口存在就返回不要求前台WinWaitActive要求窗口成为活动窗口。有些程序启动后会弹一个不可见的模态框窗口存在但永远激活不了这时会走到错误 2 分支。调用方用error判断具体原因日志里记下来比一句「脚本失败」有用得多。参数说明默认 20 秒是我在机械硬盘 冷启动场景下测出来的经验值固态盘可以压到 8 到 10 秒跑在远程桌面里就要拉到 40 秒以上。超时值的唯一标准是「目标程序最慢一次启动要多久」宁可多给 5 秒也别让脚本在客户机上莫名其妙超时。4. 文件、进程与资源打包让脚本能独立分发脚本在自己机器上跑通只是第一步发给别人时资源怎么带、路径怎么算、权限怎么处理这三件事决定它能不能活过第一周。4.1 FileInstall把配置文件塞进 exe 的正确姿势FileInstall的作用是编译时把外部文件嵌入 exe运行时释放出来。第一个参数是编译期路径相对 .au3 文件第二个是运行期路径必须绝对路径。; 编译时把 config.ini 打进 exe首次运行时释放到临时目录 Local $sCfgDir TempDir \FillForm Local $sCfg $sCfgDir \config.ini If Not FileExists($sCfg) Then DirCreate($sCfgDir) ; 第三个参数 1 目标已存在时覆盖 FileInstall(config.ini, $sCfg, 1) EndIf ; 释放失败要立刻报出来别带着空配置往下跑 If Not FileExists($sCfg) Then MsgBox(16, 错误, 配置释放失败: $sCfg) Exit 3 EndIf逻辑说明FileInstall有个很容易误解的行为——脚本以解释方式运行时它不是「嵌入后释放」而是直接复制源文件只有编译成 exe 后才是真正的嵌入。所以调试阶段看到它能用不能证明编译后也能用必须编译一次实测。参数说明第二个参数千万别写相对路径否则文件会被释放到进程的当前工作目录而当前工作目录取决于快捷方式的「起始位置」设置换个启动方式就找不到文件了。第三个参数 1 表示覆盖0 表示目标存在时跳过首次释放场景用 1 更保险避免上次残留的旧配置生效。4.2 路径ScriptDir 和 WorkingDir 不是一回事这两个宏经常被混用出了事很难查。ScriptDir是脚本或 exe 所在目录位置固定WorkingDir是进程当前工作目录可以是任何地方——从资源管理器双击、从快捷方式启动、从计划任务启动三者拿到的WorkingDir可能完全不同。; 正确以 exe 位置为基准找同级文件 Local $sIni ScriptDir \settings.ini Local $sData ScriptDir \data ; 错误示范相对路径依赖启动方式 ; Local $sIni settings.ini If Not FileExists($sIni) Then MsgBox(48, 提示, 找不到配置文件: $sIni) Exit 2 EndIf逻辑说明所有需要读写的资源都基于ScriptDir拼绝对路径只有临时文件才用TempDir。这个规则写进团队规范后脚本在不同启动方式下的行为就一致了。参数说明路径里有中文时字符串操作本身没问题但要确认脚本文件保存为 UTF-8 带 BOM否则源码里的中文路径字面量可能被解析成乱码。FileExists对不存在的路径返回 0不抛异常判断前不用做异常处理。4.3 进程与权限ProcessWait 和 #RequireAdmin 的配合拉起外部程序并等它结束用RunProcessWait这一对。Run返回进程 PID失败返回 0ProcessWait等待进程退出超时后进程还在就返回 0。; 需要管理员权限的脚本在文件顶部声明 #RequireAdmin Local $iPid Run(ScriptDir \setup.exe /S) If $iPid 0 Then Exit 4 ; 给 180 秒安装时间超时说明卡住了 If ProcessWait($iPid, 180) 0 Then ; 强制结束前先确认进程还在避免误杀 If ProcessExists($iPid) Then ProcessClose($iPid) Exit 5 EndIf逻辑说明#RequireAdmin是编译期和运行期都生效的指令解释运行时它会触发一次 UAC 提权请求编译后 exe 的清单文件里也会带上 requestedExecutionLevel。加了这个指令脚本才能操作管理员权限下才可见的窗口和服务。参数说明ProcessWait的超时单位是秒不是毫秒。ProcessClose只是发终止信号不保证进程立刻消失需要更彻底的话得配合ProcessExists轮询确认。权限这里有个必须记住的边界Windows 的 UIPI 机制会阻止低完整性级别进程向高完整性级别进程发送窗口消息。也就是说如果目标程序是以管理员身份运行的而你的脚本是普通权限ControlSend、ControlSetText会静默失败——不报错就是没反应。解决办法只有两个脚本也用#RequireAdmin提权或者让目标程序以普通权限运行。而脚本一旦提权从资源管理器往 exe 图标上拖文件又会失效这是同一个机制的反向作用后面排查章节会细说。5. 脚本换台机器就失效五类常见故障的现象、原因与处理同一份脚本开发机上跑得好好的到同事电脑上就卡住、乱码、没反应。下面五个是我实际遇到过最多次的按现象、原因、解决三段记照着对号入座基本能定位。5.1 WinWait 直接超时窗口明明开着现象脚本跑到WinWait就卡住10 秒后退出但目标窗口在屏幕上明明白白开着。原因WinTitleMatchMode默认值是 0完全匹配。目标机上的窗口标题带了文档名、版本号或用户名比如开发机是「记事本」同事机器上是「未命名 - 记事本」字符串对不上永远等不到。解决脚本开头统一设Opt(WinTitleMatchMode, 2)走包含匹配或者更稳妥地用[CLASS:Notepad]这类类名匹配。改完后用 Au3Info 重新抓一遍真实标题别靠肉眼抄。5.2 ControlSend 打不出中文英文数字却正常现象往输入框里写中文要么整段丢失要么变成问号英文和数字完全没问题。原因ControlSend投递的是字符消息中文要经过目标控件的输入法处理链路部分老控件对这个链路支持不完整另一个常见原因是脚本源文件编码不对中文字面量在解析阶段就已经损坏。解决先确认脚本文件存成 UTF-8 带 BOM这是 AutoIt 正确识别中文字符串的前提。确认编码没问题后把ControlSend换成ClipPutSend(^v)的剪贴板方案; 剪贴板方案适合中文、长文本、含特殊符号的内容 ClipPut(这是一段需要写入的中文内容) WinActivate($hWnd) WinWaitActive($hWnd, , 5) Send(^v)剪贴板方案会覆盖用户当前剪贴板内容脚本结束前最好把原内容存下来再还原这个细节后面进阶章节会补。5.3 加管理员权限后拖文件到 exe 上没反应现象脚本本来支持把文件拖到 exe 图标上处理加了#RequireAdmin之后这个功能彻底失效$CmdLine里什么都没有。原因UIPI 限制资源管理器是普通权限进程无法向高权限进程发起拖放。这不是脚本写错了是系统层面的隔离。解决放弃拖放改成在 GUI 里放一个「选择文件」按钮走FileOpenDialog或者约定用命令行参数传入路径。如果一定要保留拖放体验就只能放弃提权把需要管理员权限的那部分操作单独拆成另一个 exe 调用。5.4 编译后 FileInstall 释放的文件找不到现象源码里明明写了FileInstall解释运行没问题编译后运行目标路径下空空如也。原因第二个参数写成了相对路径文件被释放到当前工作目录而不是预期位置或者第一个参数的相对基准搞错了它是相对 .au3 文件所在目录不是相对编译输出目录。解决第二个参数一律写绝对路径用TempDir或ScriptDir拼出来释放后立刻用FileExists校验失败就弹窗把实际路径打出来比在日志里猜快得多。5.5 带界面的脚本点按钮没反应现象脚本加了简单的 GUI正常运行几分钟后界面卡死按钮点不动任务管理器显示进程还在。原因AutoIt 是单线程的GUI 消息靠GUIGetMsg轮询。如果主循环里塞了一段耗时操作或者长Sleep消息泵就停摆了界面自然假死。解决耗时逻辑用AdlibRegister挂成定时器分片执行或者把长循环拆开每轮都调一次GUIGetMsg()。带 GUI 的脚本里我基本不用超过 200 毫秒的Sleep需要等待就轮询状态别阻塞主循环。6. 给脚本加日志和退出码让失败自己说出在哪一步脚本发给别人之后最痛苦的不是它失败而是失败了你拿不到任何信息。我后来养成一个习惯所有要交付的脚本第一件事不是写业务逻辑而是先把日志和退出码框架搭好。Global $g_sLog ScriptDir \run.log Func _Log($sMsg) Local $sTime YEAR - MON - MDAY HOUR : MIN : SEC FileWriteLine($g_sLog, $sTime $sMsg) EndFunc ; 注册退出钩子无论正常结束还是异常退出都会走 OnAutoItExitRegister(_OnExit) Func _OnExit() _Log(退出 code exitCode method exitMethod) EndFunc _Log(开始执行主机 ComputerName 用户 UserName) Local $hWnd _WaitWindow([CLASS:Notepad], 10) If error Then _Log(等待窗口失败error error) Exit 10 EndIf _Log(窗口已就绪句柄 $hWnd)exitCode是脚本退出时带的值exitMethod记录退出方式正常结束、托盘退出、被注销等两个一起写进日志能区分「跑完了」和「被强杀了」。退出码我按段位约定0 成功10 到 19 是等待类失败20 到 29 是文件类失败30 以上是外部程序调用失败。外层用批处理调用时%ERRORLEVEL%直接能拿到这个码配合if errorlevel 20做分支处理比解析日志文本可靠。日志路径放在ScriptDir有个前提——exe 所在目录可写。如果放在 Program Files 下普通权限写不进去FileWriteLine会静默失败。这种场景改到TempDir \你的程序名\更稳代价是排查时要多问一句「日志在临时目录里」。从那以后我每次交付脚本都强制走一遍「编译 → 换一台没装过 AutoIt 的机器 → 只跑 exe → 看日志」这条链路日志里没有那一行「开始执行」就说明根本没启动问题在打包或权限有开始没结束问题卡在中间某一步顺着最后一条日志往下找就行。这套笨办法救过我很多次也省掉了无数次来回问「你那边具体什么现象」。希望帮到你。本文还有配套的精品资源点击获取