# AutoIt v2 用户的注意事项

## 优势

- 享受针对 AutoIt v2 近乎完整的向后兼容性，你没有必要学习新的语法和命令。
- 所有 If 类型 的命令都可以使用 Else。
- IF 和 ELSE 可以使用 区块 (多行的部分) (实际上消除 Goto 的需要)。
- 在 循环 内使用 break 和 contiue (另一种消除 Goto 的方式)。
- 使用许多新方法以及对于原有命令的改进 (如下)。
- 在你没还没有完全准备好使用它们的时候，更早地 (载入时) 而不是在后面 (运行时) 捕捉低级错误和拼写错误：捕捉语法错误作为 优化 程序的一部分。
- 更好的启动 性能。

## 运行 AutoIt v2 (.aut) 脚本

AutoHotkey 可以不需要改变最令人兴奋的 .aut 脚本而运行它们。只有以下一些 AutoIt v2 功能不支持：

- Adlib 部分 (可以使用 SetTimer)
- Break (现在在循环 中可以使用 break。)
- HideAutoItDebug

## 从 .aut 转换到 .ahk

尽管 .aut 脚本可以运行，但为了完全使用 AutoHotkey 的新功能 (如果你想改进脚本)，你应该把脚本转换到 .ahk 文件。有时你必须转换脚本，因为有些命令可以接受新的可选参数，而这些参数如果用在 AutoIt v2 脚本上会导致其中一些命令运行不正常 (细节如下)。

你可以自动把 AutoIt v2 (.aut) 脚本转换成 AutoHotkey 格式 (.ahk)。转换将把 escape 字符 转换一个重音符号 (') 而不是反斜线符号 (\)。由于每行 escape 序列的排列的原因转换比听起来更难，因此你不能仅仅在文本编辑器中运用搜索替换。自动转换功能应该可以处理所有这些细节：

1. 在 .aut 文件名后添加 .ahk，使得后缀名变为“.aut.ahk”
2. 用 AutoHotkey 运行这个文件，与直接运行这个文件不同，将在同一文件夹生成一个以“-NEW.ahk”结尾的文件。这是转换后的版本。原文件保持不变。
3. 如果你在脚本中用 #Escapechar, 请从转换后的文件中删除。

把 .aut 转换成 .ahk 后，主要就是检查在 .ahk 中支持新参数而在 .aut 中不支持的命令。如果你在转换前用非 escape 逗号做最后一个参数 (在 AutoIt v2 中) 而现在不是最后一个参数的话，这些逗号会被当做分界符。比如：

    WinActivate, title, text with literal comma, here.

上面这句在转换后就有问题了。字符串“here.”将会被认为是新的“非标题的”参数.
底下是接受新参数、有可能出问题的命令列表：
StringReplace
StringGetPos
FileSelectFile
FileRemoveDir
WinClose/Kill/Activate/Minimize/Maximize/Restore/Hide/Show
WinSetTitle/WinGetTitle
注意：即使有些命令在 .ahk 文件中接受新参数，像 IfWinExist 这样的命令也不会像上边的命令那样出问题因为程序可以区别 AutoIt v2 和 AutoHotkey 的方法。WinWait 这一系列命令也不会出现问题，MsgBox 命令同样也不会出问题因为它可以很好的处理逗号。

## 改进的语法

除了少数例外，所有命令都支持浮点数 (比如3.5) 和16进制 (比如0xFF)。

所有 IF 类的命令都支持关键字 ELSE。同时也支持 区块。比如：

原来的风格:

    IfWinExist, Notepad, , WinActivate, Notepad

新风格 (当有多行要执行时使用 {…} 标明区块) :

    IfWinExist, Untitled - Notepad
    {
        WinActivate   ; 不需要再次指明标题因为他会自动使用“最后找到的”窗口。
        WinMaximize  ; 如果没这行，这段就不需要区块 (括号)。
    }
    else
        Run Notepad

嵌套的 IF 和区块例子:

    if varx = 1
    {
        if vary = 2
            if varz = 3
                sleep, 1
            else  ; 这个 else 和最近的 IF 相匹配
                sleep, 1
    }
    else  ; 这个 else 和顶端的 IF 匹配因为区块防止它与“if vary = y”匹配
        sleep, 1

同样，区块也可以用于循环。但这第一个例子不需要区块因为 if+else 表达式只算一句：

    Loop, 5000
        IfNotExist, c:\semaphore.txt
            sleep, 1000
        else
            break  ; 提前终止循环

这个例子需要区块:

    Loop  ; 因为没有指明次数，除非遇到 Exit，Return 或是 Break，这是个无限循环。
    {
        ...
        if var <= 5
            continue  ; 跳过区段剩下的语句从区块开始下次循环。
        ...
        if var > 25
            break  ; 跳出循环。
    }

浏览文件夹内容的 文件循环 (file-loop) 的例子 (注册表循环 (registry-loops) 和 分解循环 (parsing-loops) 也支持) ：

    Loop, %A_ProgramFiles%\*.txt, , 1  ; Recurse into subfolders.
    {
        MsgBox, 4, , Filename = %A_LoopFileFullPath%`n`nContinue?
        IfMsgBox, No
            break
    }

最后，我们也支持 复杂的表达式 和 函数调用 ，比如：

    NetPrice := Price *  (1 - Discount/100)

    LargestOfTwo := Max (x, y)

    if  (CurrentSetting > 100 or FoundColor <> "Blue")
        MsgBox The setting is too high or the wrong color is present.

## AutoIt v2 和AutoHotkey 其他不同之处

AutoHotkey.exe 运行 AutoIt v2 (.aut) 脚本时：

- 反斜杠 (\) 作为 escape 字符. 但是其他脚本 (.ahk，.ini) 用重音符号 (`)。用 #EscapeChar 更改默认值。
- 支持禁用同行注释 (用 #AllowSameLineComments 启用它们)。
- 井号 (#) 可以在 Send 命令中作为注释符号。 其他脚本类型用它作为 windows 键。比如 #y 会发送 Win-Y。
- DetectHiddenText 默认是 OFF。其他脚本类型默认是 ON 因为这样更实用。
- SetBatchLines 默认是 1，意思是默认运行速度比较慢。其他脚本用 10ms。
- SetWinDelay 默认是 500。其他脚本类型默认 100，这样可以让窗口操作更快。
- 以下命令的扩展 (新的) 参数被禁用了。这是出于兼容性的考虑 (看上边的转换注意事项) ：
  MsgBox
  FileSelectFile
  FileRemoveDir
  IniRead
  StringReplace
  StringGetPos
  WinClose
  WinKill
  WinActivate
  WinMinimize
  WinMaximize
  WinRestore
  WinHide
  WinShow
  WinSetTitle
  WinGetTitle

脚本编译器 (Ahk2Exe) 不支持 AutoIt v2 (.aut) 脚本，因为编译后的脚本无法判断以 AutoIt v2 模式或是 AutoHotkey 模式运行。所以先把 .aut 脚本转换成 .aut 然后在编译它 (看上边)。

与 AutoIt v2 不同，IfGreater/Less 如果一个输入不是纯数字的话将比较字母。

IniWrite 和 IniDelete：对于 AutoIt v2 (.aut) 脚本：这两个命令没有设置 ErrorLevel。对于其他脚本来说，如果有问题，ErrorLevel 是 1，否则是 0。

InputBox： 对于 AutoIt v2 (.aut) 脚本：如果用户按了取消键，输出变量会被设成空，这样可以知道是按了取消键。对于 AutoHotkey 脚本：即使用户按了取消键，输出变量也会是用户输入的值。为了区别，如果按下取消, Alt-F4，或是X-button关闭窗口，ErrorLevel 会被设 成1。否则 ErrorLevel 是 0。这样取消键可以设置对于不同输入文本的特殊操作。

SplashTextOn：AutoIt v2 (.aut) 脚本用的 splash 窗口比 AutoHotkey 脚本中的矮些。所以如果你要转换一个 .aut 脚本到 .ahk，或是从一个 .aut 脚本拷贝粘贴代码到一个 .auk 脚本， 你可能会少掉它的标题行那么高的高度 (大概 20 像素，但是具体要看你的桌面设置)。

最后和 AutoIt v2 不一样，AutoHotkey 没有把它的 变量 存为环境变量。因为这样性能会降低而且操作系统对于这样的变量有 32KByte 的限制。要明确地将一个值存进环境变量中，用 EnvSet，而不是 SetEnv.

## 新语言和命令风格

同行注释可以在脚本扩展名不是 .aut (AutoIt v2) 的时候使用。分号可以用做这些注释的前缀字符，就跟用在整行注释的时候一样。但是分号只有在其左边至少有一个空格或是tab的时候才被当做注释的一部分。如果需要在空格或是 tab 后使用文字的 (literal) 分号，可以在它前面加上重音符号 (`)。在底下的两个例子中，变量都被符为文字的分号：
var = `;
var =;

为了方便起见，所有命令的第一个逗号可以省略 (除非第一个参数为空)。比如：Sleep 1, MsgBox test, etc.

一些命令可以选用新语法替代 AutoIt v2 的旧语法。这些命令是：

- Var = value ；可以替 代SetEnv, var, value。Value 可以是空，比如 var =
- if var <> value ；你可以用 <> != < = > 作为比较运算符替代 ifequal/notequal/greater，等等。
- var += 5 ；这个等同于 envadd, var, 5。其他运算符有 -=, *=, /=
- 但是新旧命令语法不要在同行使用：

      IfEqual, x, 35, y = 55 ；程序将无法识别 y = 55 作为 IF 的动作。
      ；应该是：
      IfEqual, x, 35, SetEnv, y, 55
      ；或是：
      IfEqual, x, 35
          y = 55

你也可以确定一个变量是否 符合 列表中的项目：
if var [not] in item1,item2,item3 ；完全匹配
if var [not] contains item1,item2,item3 ；包含

...或者一个变量是否在两个值 之间：
if var [not] between 5 and 10

...或者一个变量是否是 特定的数据类型 :
if var is number
if var is not float ； 不是浮点类型

SetTitleMatchMode 命令得到了改进：除了支持传统模式 1 和 2，现在还支持单词 fast 和 slow (比如： SetTitleMatchMode, slow)。默认是 AutoIt v2 使用的 fast。但是，对于某些窗口来说 slow 模式可以“看见”更多文本。Fast 模式速度更快，可以提高调用许多窗口命令的脚本的运行速度。Slow 模式只有当没有其他办法识别某个窗口的时候才使用。 程序所带的 Window Spy 只有在 slow 模式下才能显示窗口中哪些文字是可以使用的。

## 改进的命令

对于大多数窗口命令，比如 WinActivate 不传递任何参数会激活被 IfWinExist 或 WinWait 最近发现的 窗口。向 WinActivate 传递字母 A 作为窗口标题的值会使命令作用于当前激活的 (前台) 窗口。比如：WinClose, A 。

同样，大部分窗口命令支持 Exclude-Title 和 Exclude-Text 作为新参数。如果一个窗口的标题包含了 Exclude-Title 或是文本包含了 Exclude-Text，那么这个窗口将不合格.

StringGetPos 现在最后一个参数是一个新的可选参数。如果这个参数是字母 R，搜索会从右边而不是左边开始，并将返回最后一个符合条件的结果而不是第一个。

MouseClick 支持一个新的参数。如果是字母 D，将会一直按下按某个键直到用户手动点击它或是运行脚本中的下一个动作。如果最后一个参数是 U，按键将会被释放 (即使以前没有按它，也会发送一个释放事件 (up-event))。除此之外，你也会发现新的 Click命令 语法更简单灵活。

A_Space 和 A_Tab 是两个新的内置参数，分别代表一个空格和制表符。这样避免了需要用其他方法获取一个含有空格的变量。比如：

    String = String with spaces
    IfInString, String, %A_SPACE%
        MsgBox, A space was found.
    ; 但是要赋给一个变量单独一个空格，记得要关掉 AutoTrim，这样
    ; 赋值不会删除开头和结尾的空格：
    AutoTrim, off
    MySpace = %A_SPACE%

ClipboardAll 是一个新的内置变量，它包含所有剪贴板上的内容 (比如图片和格式)。它可以用来在内存和硬盘中备份一个或多个“已存的剪贴板” ，这些备份可以在以后恢复。这个命令尤其在脚本暂时用到剪贴板的时候有用，你不用害怕不知道用户都在上面存了什么。

Run 和 RunWait 可以运行快捷方式 (.lnk files) 、文档，和网址。比如：

    Run, www.yahoo.com
    RunWait, New Document.doc

除此之外，也支持一些系统动作：properties、edit、print、find、explore、open和print。比如：

    Run, properties c:\autoexec.bat ; 打开这个文件的属性对话框。
    Run, edit %A_SCRIPTFULLPATH% ; 执行与这个文件相关联的“edit”动作 (如果它有的话)。

Send 和 ControlSend 功能也得到了改进。你不需要用 Sleep 命令让用户有时间释放用 Send 命令发送的修饰键 (Ctrl/Alt/Shift/Win) 和热键。对于每个键，Send 命令知道应该把修饰键变成什么发送出去。

StringReplace 可以替换所有搜索到的结果，只要把最后的参数设为“A”。

StringGetPos 现在在命令最后支持新的参数。如果这个参数是字母 R，搜索将从右边开始而不是左边。也就是说将返回最后一个出现的结果而不是第一个。

MsgBox 在最后支持一个新的可选参数：Timeout (按秒计算，经过多少秒 MsgBox 会关闭。 IfMsgBox 在这种情况下可以看到TIMEOUT的值)。处于兼容性的考虑，只有当脚本名扩展名不是 .aut 的时候这个新的参数才可以用。

IniRead 在最后支持一个新的可选参数：如果命令失败，默认赋予输出变量的值。处于兼容性的考虑，只有当脚本名扩展名不是 .aut 的时候这个新的参数才可以用。

FileSelectFile 加入了很多新功能。

## 新命令和功能

下面介绍一些最值得注意的新命令和功能：

GUI：生成并管理图形用户界面 (GUI) 窗口和控件。生成你自己有专业外观的应用程序和表格而不用考虑复杂的编程语言。

Menu：生成你自己定制的菜单栏，系统托盘图标菜单，和弹出菜单。

Hotkeys：用于键盘，游戏杆和鼠标。

Hotstrings：当你键入它们的时候，这些缩写会自动扩展开 (自动替换)。

DllCall：调用 DLL 中的函数，比如标准 Windows API 函数。

OnMessage：定义当脚本收到某个特定消息时 (从操作系统、外部程序或是其他脚本) 自动运行的 函数。

SendInput 和 SendPlay：这两个新方法用于快速可靠地发送键击和鼠标手势的。而且，SendPlay 比起其他命令可以向更多种类的游戏发送键击和鼠标手势。

Progress 和 SplashImage：显示进度条和图像，以及可选文字。

OnExit：可以定义当脚本退出时自动运行的程序。脚本也可以用它检测是否用户注销或是关机。

Process：对一个进程执行如下之一的操作：检查是否存在；更改优先级；关掉它；等待它关闭。

SoundSet：更改一个音频设备的设置 (主设备静音，主设备音量等等。)

SetTimer：在自定义时间间隔内执行一个或多个程序。

ClipWait：等待剪贴板包含文字 (变成非空)。

StatusBarWait：等待一个窗口的状态栏包含特定文字或是变成空。

StatusBarGetText：获取状态栏的文字。

WinActivateBottom：这个命令与 WinActivate 相似但是是激活最老的 (最底层的) 窗口而不是最新的。如果只有一个窗口，结果将和 WinActivate 一样。

DriveSpaceFree, DriveGet 和 Drive：获取并改变一个分区的信息 (比如它的可用空间)。

AutoTrim，on/off (默认 on) ：当你给一个变量赋值时，它控制是否自动删掉字符串左右的空格。由于这个原因，空格是指空格和制表符而换行符 (newline 或是 linefeed) 则不包括在诶。因此我相信“on”和 Autoit v2 中的效果是一样的。

StringUpper 和 StringLower：将一个字符串转换成大写或是小写。

ControlFocus，ControlSetText，Control，ControlGet：和其他 Control 命令直接控制一个窗口的控件。

SoundPlay：播放任何操作系统支持的媒体文件。

SoundGet，SoundSet，和 SoundSetWaveVolume：获取并改变一个声音设备的设置 (主设备静音，主设备音量，波形音量等。)

PixelGetColor 和 PixelSearch：这两个命令可以获得屏幕上某点的颜色，可以用于得知一个应用程序或是游戏的状态是否改变了。

GetKeyState：检测一个键，鼠标或是游戏杆的键是否按下或放开；检测游戏杆的位置；等。

WinMenuSelectItem：不管目标窗口是否被激活，直接运行菜单栏项目。

#AllowSameLineComments：为了提高和 AutoIt v2 的兼容性，以.aut 结尾的脚本通常不允许有同行注释 (比如：Run, notepad ; this is a comment)。要允许同行注释可以在你的脚本第一行加上 #AllowSameLineComments

#SingleInstance：在脚本的任何地方加上这行可以避免运行两个脚本实例。同时，你可以选择是保留原有的实例还是用新的替换掉原有的。

#EscapeChar：escape 字符通常是“`”，但你也可以用 AutoIt v2 中的 escape 字符 (\) 或是其他你选择的字符。注意 .aut 结尾的脚本默认使用\作为 escape 字符的。

Suspend (和托盘菜单具有相同名字的选项) ：这个函数阻止新的热键运行 (它无法停止已经运行的热键功能--要停止的话可以用 Pause)。

Pause (和托盘菜单具有相同名字的选项) ：和 Suspend 不同--它完全停止了热键 --pause 会暂停正在运行的程序 (如果没有，pause 不会有任何影响)。

文件和文件夹循环、注册表循环、以及功能更强的 循环。

加入了 窗口组 的概念。一旦定义了一个组，这个组就可以用于 GroupActivate 命令。

最后，还有其他许多命令。你可以从 按字母排序的命令列表 中查看。