变量和表达式

目录

变量

有关一般说明和变量如何工作的详细信息, 请参阅变量.

给变量赋值: 要将字符串或数字存储在变量中, 使用冒号-等号运算符(:=) 后跟着数字, 加引号的字符串或其他类型的表达式. 例如:

MyNumber := 123
MyString := "这是原义字符串."
CopyOfVar := Var

变量不能被显式删除, 但是它的前一个值可以通过赋值一个新的值来释放, 比如一个空字符串:

MyVar := ""

变量也可以间接赋值, 通过获取它的引用, 并使用双重解引或将其传递给一个函数. 例如:

MouseGetPos &x, &y

读取一个没有赋值的变量的值被视为一个错误. IsSet 可以用来检测这种情况.

检索变量的内容: 若要将变量的内容包含在字符串中, 请使用连接Format. 例如:

MsgBox "变量的值是 " . Var . "."
MsgBox "变量 Var 中的值为 " Var "."
MsgBox Format("Var has the value {1}.", Var)

子表达式可以以同样的方式与字符串组合. 例如:

MsgBox("X 和 Y 的和是 " . (X + Y))

变量的比较: 请阅读下面表达式部分中关于不同类型比较的重要提示.

表达式

有关结构化概述和进一步说明, 请参阅表达式.

表达式用于对一系列变量, 原义字符串和/或原义数字执行一个或多个运算.

表达式中的普通单词被解释为变量名. 因此, 原义的字符串必须用双引号括起来, 以便与变量区分开来. 例如:

if (CurrentSetting > 100 or FoundColor != "Blue")
    MsgBox "设置太高或出现错误的颜色."

在上面的例子中, "Blue" 出现在引号中, 因为它是一个原义的字符串. 单引号(') 和双引号(") 的作用是相同的, 除了用单引号括起来的字符串可以包含原义双引号, 反之亦然. 因此, 要在原义字符串中包含 真实的 引号, 可以转义引号或将字符串括在相反类型的引号中. 例如:

MsgBox "她说, `"一天一个苹果.`""
MsgBox '她说, "一天一个苹果."'

空字符串: 若要在表达式中指定空字符串, 请使用一对空的双引号. 例如, 当 MyVar 非空时, 语句 if (MyVar != "") 的结果为真.

保存表达式的结果: 要把结果赋值给变量, 请使用冒号-等号运算符(:=). 例如:

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

布尔值: 若要计算表达式结果为真还是假时(如 IF-语句), 结果为空或零被视为假(false), 而其他所有结果都视为真(true). 例如, 仅当 ItemCount 为空或 0 时, 语句 if ItemCount 的结果才为假. 类似的, 表达式 if not ItemCount 将产生相反的结果.

诸如 NOT/>/=/< 之类的运算符自动生成一个真值或假值: 真值时结果为 1, 而假值时为 0. 然而, AND/OR 运算符总是生成一个输入值. 例如, 在以下表达式, 如果 A_Index 大于 5, 变量 Done 赋值为 1, 其他情况下为 FoundIt 的值:

Done := A_Index > 5 or FoundIt

如上所述, 可以通过将变量设为空或赋值为 0, 来使变量来保存假值. 利用这种特性, 可以使用简写语句 if Done 来检查变量 Done 是真还是假.

在表达式中, 关键字 truefalse 解析为 1 和 0. 使用它们可以使脚本更易于阅读, 如以下示例所示:

CaseSensitive := false
ContinueSearch := true

整数和浮点数: 在表达式中, 如果数字包含小数点或科学计数符号, 则认为它们是浮点数; 否则, 否则视为整数. 对于大多数运算符 -- 如加法和乘法 -- 只要其中的一个输入是浮点数, 那么结果也将是浮点数.

在表达式和非表达式中, 整数都可以用十六进制或十进制格式书写. 十六进制数总是以前缀 0x 开头. 例如, Sleep 0xFF 等同于 Sleep 255. 浮点数可以选择用科学记数法书写, 带或不带小数点(例如 1e4-2.1E-4).

在脚本开始执行之前, 在表达式中, 未加双引号的原义数字(如 128, 0x7F1.0), 被转换为纯数字, 因此将数字转换为字符串可能会产生与原始文字值不同的值. 例如:

MsgBox(0x7F)  ; 显示 128
MsgBox(1.00)  ; 显示 1.0

表达式中的运算符

有关运算符的一般信息, 请参阅运算符.

除了下面提到的, 数学运算中涉及的任何空值(空字符串) 或非数字值都不会假定为零. 相反, 会抛出 TypeError. 如果未使用 Try, 默认情况下, 未处理的异常将导致一个错误对话框.

表达式运算符(按优先级降序排列)

运算符 描述
%Expr%

解引用名称替换.

Expr 计算为 VarRef 时, %Expr% 访问相应的变量. 例如, x := &yy 的引用并将其赋值给 x, 那么 %x% := 1 赋值给变量 y, 而 %x% 读取其值.

否则, 子表达式 Expr 的值被用作变量或属性的名称或部分名称. 这使得脚本可以引用一个变量或属性, 其名称是由计算 Expr 确定的, 它通常是另一个变量. 变量不能被动态创建, 但是如果一个变量已经在脚本中的某个地方被声明或被非动态引用, 那么它可以被动态赋值.

注意: 子表达式 Expr结果 必须是要访问的变量或属性的名称或部分名称.

由于存在歧义, 百分号不能直接在 Expr 中使用, 但可以在括号中嵌套. 否则, Expr 可以是任何表达式.

如果有任何相邻的 %Expr% 序列和部分名称(它们之间没有任何空格或其他字符), 则将它们组合成一个单一的名称.

如果变量并不存在, 或者它未初始化并且它的值正在被读取, 则通常抛出一个 Error. 可以使用 or-maybe 运算符(??) 通过提供默认值来避免这种情况. 例如: %'novar'% ?? 42.

虽然这在历史上被称为 "双重解引", 但当 Expr 不包含一个变量(第一重解引), 以及当产生的变量是赋值的目标, 而不是解引用(第二重解引), 这个术语是不准确的.

x.y
x.%z%
成员访问. 获取或设置一个值或调用对象 x 的方法, 此处 y 是个原义名称, 而 z 是一个表达式, 它的值是一个名称. 请参阅对象语法.
var?

Maybe. 允许未设置的变量. 这只在将变量传递给可选参数, 数组元素或文本对象; 或直接赋值的右边时有效. 问号后面必须跟随下列符号之一(忽略空白): )]},:. 变量可以通过三元运算符或在 AND/OR 的右边有条件地传递.

变量通常是一个可选参数, 但可以是任何变量. 对于不是函数参数的变量, 如果有对该变量的其他引用但没有赋值, 在加载时仍然可能显示 VarUnset 警告.

该操作符目前仅支持变量. 要在更一般的情况下显式或有条件地省略参数, 请使用 unset 关键字.

另请参阅: unset(可选参数)

++
--

前置和后置的自增/自减. 从变量中增加或减去 1. 运算符可以放在变量名的前面或后面. 如果放在变量名的 前面, 则执行自增/减运算并把结果用于下一运算(在这种情况下结果是一个变量引用). 例如, Var := ++X 递增 X 然后将其值赋给 Var. 相反, 如果运算符放在变量名的 后面, 结果是在执行运算之前的 X 值. 例如, Var := X++ 递增 X, 但 Var 接收 X 在递增之前的值.

这些运算符还可以与对象的属性一起使用, 如 myArray.Length++--myArray[i]. 在这些情况下, 子表达式的结果总是一个数字, 而不是一个变量引用.

**

. 示例用法: Base**Exponent. 底数(Base) 和指数(Exponent) 都可以为小数. 如果 指数 为负数, 即使 底数指数 都为整数, 结果也会被格式化为浮点数. 因为 ** 的优先级高于一元负号, 所以, -2**2 的计算过程和 -(2**2) 一样, 且得到结果 -4. 因此, 要计算原义负数的幂, 需要把它们包围在括号中, 如 (-2)**2.

幂运算符是右结合的. 例如, x ** y ** z 计算为 x ** (y ** z).

注意: 不支持 底数 为负数且 指数 为小数的情况, 如 (-2)**0.5; 尝试它将导致抛出异常. 但 (-2)**2(-2)**2.0 都是支持的. 如果 底数指数 都为 0, 结果未定义并抛出异常.

-
!
~
&

一元负号(-): 反转其运算元的符号.

一元正号(+): +N 等同于 -(-N). 应用于纯数字时无效, 但可用于将数字字符串转换为纯数字.

逻辑非(!): 如果运算元为空或 0, 那么逻辑非的结果为 1, 这表示 "true". 否则, 结果为 0(false). 例如: !x or !(y and z). 注意: 单词 NOT 和 ! 含义相同, 但 ! 优先级更高. 允许使用连续的一元运算符, 例如 !!Var, 因为它们是按从右到左的顺序计算.

按位非(~): 此运算符对运算元按位取反. 当使用 64 位有符号整数时, 正的输入值始终给出负的结果, 反之亦然. 例如, ~0xf0f 等于 -0xf10(-3856), 二进制等于 0xfffffffffffff0f0. 如果希望使用无符号的 32 位值, 可以使用 result & 0xffffffff 截断结果. 如果操作数是一个浮点值, 则抛出 TypeError.

引用(&): 创建一个 VarRef, 它是一个代表变量引用的值. VarRef 可以用来间接访问目标变量. 例如, ref := &target 接着的 %ref% := 1 将把值 1 赋值给 target. VarRef 通常会被传递给一个函数, 但也可以存储在一个数组或属性中. 另请参阅: Dereference, ByRef.

目前不支持对内置变量(如 A_Clipboard) 的引用, 除非是直接传递给内置函数的 OutputVar 参数.

*
/
//

乘(*): 如果两个输入都为整数, 则结果为整数; 否则结果为浮点数.

其他用途: 星号(*) 运算符也用于可变参数函数调用.

真除(/): 即使两个输入都是整数, 真除的结果也为浮点数. 例如, 3/2 结果为 1.5 而不是 1, 而 4/2 结果为 2.0 而不是 2.

整数除法(//): 如果两个输入都是整数, 那么双斜杠运算符使用高效的整数除法. 例如, 5//3 结果为 1 而 5//-3 结果为 -1. 如果任何一个输入为浮点格式, 则抛出 TypeError. 有关取模, 请参阅 Mod.

*= 和 /= 运算符是用变量的值乘以或除以另一个值的一种简写形式. 例如, Var*=2Var:=Var*2 会得到相同的结果(不过前者执行的更好).

除数为零, 则导致抛出 ZeroDivisionError.

+
-

加(+)减(-). 在相关的注释中, +=-= 运算符是变量增加或减少的一种简写形式. 例如, Var+=2Var:=Var+2 会得到相同的结果(不过前者执行的更好). 类似地, 变量可以通过使用 Var++, Var--, ++Var 或 --Var 来增加或减少 1.

其他用途: 如果 + 或 - 符号前面没有一个值(或生成值的子表达式), 则将其解释为一元运算符.

<<
>>
>>>

按位左移(<<). 使用示例: Value1 << Value2. 这相当于 Value1 乘以 "2 的 Value2 次幂".

算术位右移(>>). 使用示例: Value1 >> Value2. 这相当于 Value1 除以 "2 的 Value2 次幂" 并将结果四舍五入到数轴左侧最接近的整数; 例如, -3>>1 结果为 -2.

逻辑位右移(>>>). 使用示例: Value1 >>> Value2. 与算术位右移不同, 这并不保留数字的符号. 例如, -1 与无符号的 64 位整数 0xffffffffffffffff 拥有相同的位表示, 因此 -1 >>> 1 结果为 0x7fffffffffffffff.

下面的内容适用于所有三个运算符:

  • 如果任何一个输入是浮点数, 则抛出 TypeError.
  • 如果 Value2 小于 0 或大于 63, 则抛出异常.
&
^
|

按位与(&), 按位异或(^)按位或(|). 这三个运算符中, & 优先级最高, 而 | 优先级最低.

如果其中一个输入是浮点数, 则抛出 TypeError.

相关: 按位非(~)

.

连接. 每边至少有一个空格或制表符的句点(点) 用于将两个项组合成单个字符串. 您还可以省略句点以获得相同的结果(除非有歧义, 如 x -y, 或者右边的项有一个前导的 ++ 或 --). 当省略点时, 要合并的项之间必须至少有一个空格或制表符.

Var := "The color is " . FoundColor  ; 显式连接
Var := "The color is " FoundColor    ; 自动连接

还可以用来连接子表达式. 例如: Var := "The net price is " . Price * (1 - Discount/100).

以句点(或其他任何运算符) 开始的行会自动附加到上一行的末尾.

每个输入的整个长度会被使用, 即使它包含二进制零. 例如, Chr(0x2010) Chr(0x0000) Chr(0x4030) 生成以下字节的字符串(由于 UTF-16-LE 编码): 0x10, 0x20, 0, 0, 0x30, 0x40. 结果有一个额外的空结束符(二进制零), 它不包含在长度中.

其他用途: 如果句点右侧没有空格或制表符, 则将其解释为原义浮点数成员访问. 例如, 1.1(.5) 是数字, A_Args.Has(3) 方法调用, 而 A_Args.Length 是一个属性访问.

~= RegExMatch 的简写形式. 例如, "abc123" ~= "\d" 结果为 4(首个数字字符串的位置).
>   <
>= <=

大于(>), 小于(<), 大于或等于(>=)小于或等于(<=). 输入的数据是以数字方式进行比较的. 如果其中一个输入不是数字或数字字符串, 则抛出 TypeError.

=
==
!=
!==

不区分大小写的等号(=) / 不等号(!=)区分大小写的等号(==) / 不等号(!==). 运算符 == 的行为和 = 是一样的, 除非其中一个输入不是数字(或都是字符串), 在这种情况下 == 总是区分大小写的, 而 = 总是不区分大小写的. !=!== 与其对应的没有 ! 的运算符是一样的, 只是其结果取反.

==!== 运算符可用于比较包含二进制零的字符串. 除了 ~= 之外的所有其他比较运算符仅比较到第一个二进制零.

对于不区分大小写的比较, 只有 ASCII 字母 A-Z 才会被认为等同于它们的小写字母. 如果要根据当前用户区域规则进行比较, 请使用 StrCompare 并为 CaseSense 参数指定 "Locale".

IS
IN
CONTAINS

如果 ValueClass 的实例, 那么 Value is Class 结果为 1(true), 否则为 0(false). Class 必须是一个对象, 并具有自有 Prototype 属性, 但通常该属性是由类定义隐式定义的. 这个操作一般等同于 HasBase(Value, Class.Prototype).

incontains 保留给将来使用.

NOT 逻辑非. 除了优先级较低外, 其他的与 ! 运算符相同. 例如, not (x = 3 or y = 3) 等同于 !(x = 3 or y = 3).
AND
&&

这两个运算符都是逻辑与. 例如: x > 3 and x < 10.

dddddd

在表达式中, 所有 运算元都解析为 True, 则返回 最后解析为 True 的运算元. 否则, 返回 第一个 解析为 False 的运算元. 实际上, 只有当所有运算元都为 true 时, 结果才为 true. 布尔表达式需要进行求值优化(从左到右) 以提高性能.

In an expression where all operands are true, the last operand is returned. Otherwise, the first operand that is false is returned. In other words, the result is true only if all operands are true. Boolean expressions are subject to short-circuit evaluation (from left to right) to improve performance.

在下面的例子中, 所有运算元都为真, 并都要进行计算:

A := 1, B := {}, C := 20, D := true, E := "str"
MsgBox(A && B && C && D && E) ; 显示 "str"(E).

在下面的例子中, 因为 B 为假, 所以只计算前两个运算元. 其余部分被忽略, 即 C 不递增:

A := 1, B := "", C := 0, D := false, E := "str"
MsgBox(A && B && ++C && D && E) ; 显示 ""(B).

AND&&(或其他任何运算符) 开始的行会自动附加到上一行的末尾.

OR
||

这两个运算符都是逻辑或. 例如: x <= 3 or x >= 10.

dddddd

在表达式中 至少 有一个运算元为 True, 则返回 第一个 解析为 True 的运算元. 否则, 则返回 最后 解析为 False 的运算元. 实际上, 只要有一个运算元为真, 结果就为真. 布尔表达式需要进行求值优化(从左到右) 以提高性能.

In an expression where at least one operand is true, the first operand that is true is returned. Otherwise, the last operand that is false is returned. In other words, if at least one operand is true, the result is true. Boolean expressions are subject to short-circuit evaluation (from left to right) to improve performance.

在下面的示例中, 至少有一个运算元为真. 直到 D(包括) 的所有运算元都要进行计算. E 被忽略, 并始终不会自增:

A := "", B := false, C := 0, D := "str", E := 20
MsgBox(A || B || C || D || ++E) ; 显示 "str"(D).

在下面的例子中, 所有运算元都为假, 并都要进行计算:

A := "", B := false, C := 0
MsgBox(A || B || C) ; 显示 "0"(C).

OR||(或其他任何运算符) 开始的行会自动附加到上一行的末尾.

??

Or maybe, 也称为合并运算符. 如果左操作数(必须是一个变量) 有一个值, 它就成为结果, 并跳过右分支. 否则, 右操作数将成为结果. 换句话说, A ?? B 的行为类似于 A || B (逻辑或), 除了条件是 IsSet(A).

这通常用于在已知变量或可选参数可能还没有值时提供默认值. 例如:

MsgBox MyVar ?? "Default value"

由于期望变量有时未初始化, 因此在这种情况下不会抛出错误. 与 IsSet(A) ? A : B 不同的是, 如果变量有其他引用但没有赋值, VarUnset 警告仍然可以在加载时显示.

?:

三元运算符. 此运算符是 if-else 语句的简写形式. 它计算左侧的条件来决定两个分支中哪个作为最终结果. 例如, var := x>y ? 2 : 3, 当 x 大于 y 时保存 2 到 Var; 否则保存 3. 为了提高性能, 只计算决定性的分支(请参阅求值优化).

另请参阅: maybe(var?), or-maybe(??)

注意: 当在行的开头使用时, 三元条件通常应该用括号括起来, 以减少与其他类型语句的歧义. 有关详情, 请参阅表达式语句.

:=
+=
-=
*=
/=
//=
.=
|=
&=
^=
>>=
<<=
>>>=

赋值. 对变量的内容进行运算, 然后把结果保存到同一个变量中. 最简单的赋值运算符为冒号等号(:=), 它把表达式的结果保存到变量中. 关于其他运算符的功能说明, 请参阅这个表格中它们的相关条目. 例如, Var //= 2 执行整数除法Var 除以 2, 然后把结果保存回 Var. 类似的, Var .= "abc"Var := Var . "abc" 的一种简写形式.

与其他大多数运算符不同, 赋值运算是从右往左执行的. 因此, Var1 := Var2 := 0 这个语句中首先把 0 赋值给 Var2, 然后把 Var2 赋值给 Var1.

如果赋值作为某些其他运算符的输入, 它的值是变量本身. 例如, 如果 Var 的新增值大于 50, 表达式 (Var+=2) > 50 为真. 将赋值与引用操作符结合起来也是有效的, 如 &(Var := "initial value").

需要避免语法错误或提供更直观的操作时, 会自动提升赋值运算符的优先级. 另外, x==y && z:=1 计算为 x==y && (z:=1), 当 x 不等于 y 时进行短路计算. 例如: not x:=y 等同于 not (x:=y). 类似的, ++Var := X 等同于 ++(Var := X); 而 Z>0 ? X:=2 : Y:=2 等同于 Z>0 ? (X:=2) : (Y:=2).

目标变量可以通过将直接赋值(:=) 与 unset 关键字或 maybe(var?) 运算符联合使用来 un-set(取消设置). 例如: Var := unset, Var1 := (Var2?).

赋值还可以针对对象的属性, 如 myArray.Length += nmyArray[i] .= t. 当赋值给一个属性时, 子表达式的结果是赋值的值, 而不是变量引用.

() => expr

胖箭头函数. 定义一个简单的函数并返回一个 Func闭包对象. 将函数的参数列表(可以在前面加上函数名) 写在操作符的左边. 当函数被调用时(通过返回的引用), 它计算子表达式 expr 并返回结果.

下面两个例子是等价的:

sumfn := Sum(a, b) => a + b
Sum(a, b) {
    return a + b
}
sumfn := Sum

在这两种情况下, 函数都是在脚本启动时无条件定义的, 但是函数引用只有在赋值时才存储在 sumfn 中.

如果函数名被省略, 而参数列表只包含一个参数名, 则可以省略圆括号. 下面的例子定义了一个带有一个参数 a 的匿名函数, 并将其引用存储在变量 double 中:

double := a => a * 2

expr 中的变量引用的解析方法与完整函数定义中的方法相同. 例如, expr 可以引用 outer 函数的局部变量(就像在任何嵌套函数中一样), 在这种情况下, 每当计算胖箭头表达式时, 都会创建一个新的闭包并返回它. 因为不能使用声明, 所以该函数总是假定-局部的.

为函数指定名称允许递归地调用它或由其他嵌套函数调用它, 而无需在其内部存储对闭包的引用(从而创建有问题的循环引用). 它还有助于调试, 比如 Func.Name 或显示在调试器的调用堆栈上.

胖箭头语法也可以用来定义简写的属性方法.

,

逗号(多语句). 逗号可以用来在单行中书写多个子表达式. 最常用于把多个赋值或函数调用聚集在一起. 例如: x:=1, y+=2, ++index, MyFunc(). 这样的语句按从左到右的顺序执行.

注意: 以逗号(或其他任何运算符) 开始的行会自动附加到上一行的末尾. 另请参阅: 逗号的性能.

逗号还用于分隔函数调用的或控制流语句的参数. 若要在参数列表中包含多语句表达式, 请用一组额外的圆括号将其括起来. 例如, MyFn((x, y)) 计算 x 和 y, 但传递 y 作为 MyFn 的第一个也是唯一一个参数.

逗号运算符通常比单独编写的表达式执行得更好, 特别是当将一个变量赋值给另一个变量时(例如 x:=y, a:=b). 随着越来越多的表达式被组合成单个表达式, 性能不断提高; 例如, 将五个或十个简单表达式组合成一个表达式可能会快 35 %.

下面列出的子表达式类型覆盖计算的优先级/顺序:

表达式 描述
(表达式)

括号中包含的任何子表达式. 例如, (3 + 2) * 2 强制首先计算 3 + 2.

对于多语句表达式, 将返回 最后 一条语句的结果. 例如, (a := 1, b := 2, c := 3) 返回 3.

Mod()
Round()
Abs()

函数调用. 在函数名称或表达式与参数列表开头的左圆括号之间不能有空格. 有关详情, 请参阅函数调用.

(表达式) 不一定要用括号括起来, 但这样做可以消除歧义. 例如, (x.y)() 从一个属性中检索一个函数, 然后没有参数调用它, 而 x.y() 将隐式地传递 x 作为第一个参数.

(expression)()

Fn(Params*)

可变参数函数调用. Params 是一个可枚举的对象(具有 __Enum 方法的对象), 例如包含参数值的数组.

x[y]
[a, b, c]

项目访问. 使用参数 y(或代替 y 的多个参数) 获取或设置对象 x__Item 属性(或默认属性). 这通常对应于集合中的数组元素或项目, 其中 y 是项目的索引或键. 项目可以在右方括号后使用任何赋值运算符来赋值. 例如, x[y] := z.

数组标识符(数组字面量). 如果左方括号前面没有值(或者一个产生值的子表达式), 它被解释为一个数组的开始. 例如, [a, b, c] 等同于 Array(a, b, c)(a, b 和 c 都是变量).

有关常见用法, 请参阅数组Map(映射).

{a: b, c: d}

对象标识符(对象字面量). 创建一个对象. 其中的每一对项目由一个原义的属性名称 a 和一个属性值表达式 b 组成. 例如, x := {a: b} 等同于 x := Object(), x.a := b. 可以在对象文本中设置 Base, 但是所有其他属性都设置为 自有的属性, 可能会覆盖从基对象继承的属性.

要使用动态属性名, 请将子表达式用百分号括起来. 例如: {%nameVar%: valueVar}.

内置变量

下面的变量被内置到程序中, 可以被任何脚本引用.

有关一般信息, 请参阅内置变量.

目录

特殊字符

变量 描述
A_Space 包含单个空格字符.
A_Tab 包含单个 tab(制表符) 字符.

脚本属性

dddddd
变量 描述
A_Args 包含一个命令行参数数组. 有关详情, 请参阅向脚本传递命令行参数.
A_WorkingDir

可以用来获取或设置脚本当前工作目录, 这是访问文件的默认路径. 除非是根目录, 否则路径末尾不包含反斜杠. 两个示例: C:\C:\My Documents.

使用 SetWorkingDir 或赋值路径到 A_WorkingDir 可以改变当前工作目录.

无论脚本是如何启动的, 脚本的工作目录默认为 A_ScriptDir.

dddddd

Can be used to get or set the script's current working directory, which is where files will be accessed by default. The final backslash is not included unless it is the root directory. Two examples: C:\ and C:\My Documents.

SetWorkingDir can also be used to change the working directory.

The script's working directory defaults to A_ScriptDir, regardless of how the script was launched.

A_InitialWorkingDir 脚本的初始工作目录, 由它的启动方式决定. 例如, 如果它是通过快捷方式运行的 -- 比如在开始菜单 -- 它的初始工作目录是由快捷方式属性中的 "起始位置" 字段决定的.
A_ScriptDir

当前脚本所在目录的完整路径. 不包含最后的反斜杠(根目录同样如此).

如果脚本文字是从标准输入中读取的而不是从文件中读取的, 变量值为初始工作目录.

A_ScriptName dddddd

可以用来获取或设置 MsgBox, InputBox, FileSelect, DirSelect 和 Gui 的默认标题. 如果脚本没有设置, 它默认为当前脚本的文件名, 不包括路径, 例如 MyScript.ahk.

如果脚本文字是从标准输入中读取的而不是从文件中读取的, 默认值为 "*".dddddd

Can be used to get or set the default title for MsgBox, InputBox, FileSelect, DirSelect and Gui. If not set by the script, it defaults to the file name of the current script, without its path, e.g. MyScript.ahk.

If the script text is read from stdin rather than from file, this variable contains an asterisk (*).

如果脚本是编译的嵌入的, 这就是当前可执行文件的名称.

A_ScriptFullPath

当前脚本的完整路径, 例如 C:\Scripts\My Script.ahk

如果脚本文字是从标准输入中读取的而不是从文件中读取的, this variable contains an asterisk (*).

如果脚本是编译的嵌入的, 这就是当前可执行文件的完整路径.

A_ScriptHwnd 脚本的主窗口(隐藏的) 的唯一 ID(HWND/句柄).
A_LineNumber

脚本(或其 #Include 文件) 中正在执行的行的行号. 这个行号与 ListLines 显示的一致; 它对于错误报告非常有用, 比如这个例子: MsgBox "Could not write to log file (line number " A_LineNumber ")".

由于已编译脚本已经把它所有的 #Include 文件合并成一个大脚本, 所以它的行号可能与它在未编译模式运行时不一样.

A_LineFile

A_LineNumber 所属文件的完整路径和名称. 如果脚本是从外部文件加载的, 这等同于 A_ScriptFullPath, 除非该行属于脚本的 #Include 文件之一.

如果脚本是基于一个 .bin 文件编译的, 这就是当前可执行文件的完整路径和名称, 等同于 A_ScriptFullPath.

如果脚本是嵌入的, A_LineFile 包含一个星号(*) 后面是资源名称; 例如 *#1

A_ThisFunc 当前正在执行的自定义函数的名称(没有则为空); 例如: MyFunction. 另请参阅: Name 属性(Func)
A_AhkVersion 包含了运行当前脚本的 AutoHotkey 主程序的版本号, 例如 1.0.22. 在已编译脚本中, 它包含了原来编译时使用的主程序的版本号. 格式化的版本号使得脚本可以使用 > 或 >= 来检查 A_AhkVersion 是否大于某个最小的版本号, 如这个例子所示: if (A_AhkVersion >= "1.0.25.07").
A_AhkPath

对于非编译的或嵌入的脚本: 实际运行当前脚本的 EXE 文件的完整路径和名称. 例如: C:\Program Files\AutoHotkey\AutoHotkey.exe

对于基于 .bin 文件编译脚本, 该值是通过从注册表中读取安装目录并附加 "\AutoHotkey.exe" 来确定的. 如果没有安装 AutoHotkey, 该值为空. 等同于下面的例子:

InstallDir := RegRead("HKLM\SOFTWARE\AutoHotkey", "InstallDir", "")
AhkPath := InstallDir ? InstallDir "\AutoHotkey.exe" : ""

对于基于 .exe 文件的编译脚本, A_AhkPath 包含编译脚本的完整路径. 这可以与 /script 结合使用来执行外部脚本. 如果要找到已安装的 AutoHotkey 副本, 请按上面所示读取注册表.

A_IsCompiled 如果当前运行的脚本为已编译 EXE 时, 此变量值为 1, 否则为 0(这会被视为 false).

日期和时间

变量 描述
A_YYYY

4 位数表示的当前年份(例如 2004). 与 A_Year 含义相同.

注意: 要检索符合您区域设置和语言的格式化时间或日期, 请使用 FormatTime()(时间和长日期) 或 FormatTime(, "LongDate")(检索长格式日期).

A_MM 2 位数表示的当前月份(01-12). 与 A_Mon 含义相同.
A_DD 2 位数表示的当前月份的日期(01-31). 与 A_MDay 含义相同.
A_MMMM 使用当前用户语言表示的当前月份的全称, 例如 July
A_MMM 使用当前用户语言表示的当前月份的简称, 例如 Jul
A_DDDD 使用当前用户语言表示的当前星期几的全称, 例如, Sunday
A_DDD 使用当前用户语言表示的当前星期几的简称, 例如 Sun
A_WDay 1 位数表示的当前星期经过的天数(1-7). 在所有区域设置中 1 都表示星期天.
A_YDay 当前年份中经过的天数(1-366). 不会使用零对变量的值进行填充, 例如检索到 9, 而不是 009. 要检索零填充的值, 请使用: FormatTime(, "YDay0").
A_YWeek 符合 ISO 8601 标准的当前的年份和周数(例如 200453). 要分离年份和周数, 请使用 Year := SubStr(A_YWeek, 1, 4)Week := SubStr(A_YWeek, -2). A_YWeek 的准确定义为: 如果含有 1 月 1 日的星期内有四天或四天以上在新年里, 则它被认为是新年的第一个星期. 否则, 它为前一年的最后一个星期, 而下一星期为新年的第一个星期.
A_Hour 在 24 小时制(例如, 17 表示 5pm) 中 2 位数表示的当前小时数(00-23). 要获取带 AM/PM 提示的 12 小时制的时间, 请参照此例: FormatTime(, "h:mm:ss tt")
A_Min

2 位数表示的当前分钟数(00-59).

A_Sec 2 位数表示的当前秒数(00-59).
A_MSec 3 位数表示的当前毫秒数(000-999). 要移除前导零, 请参照此例: Milliseconds := A_MSec + 0.
A_Now

YYYYMMDDHH24MISS 格式表示的当前本地时间.

注意: 可以使用 DateAddDateDiff 执行日期和时间的数学运算. 此外, FormatTime 可以根据您的区域设置或选项来格式化日期和/或时间.

A_NowUTC YYYYMMDDHH24MISS 格式表示的当前的协调世界时(UTC). UTC 本质上和格林威治标准时间(GMT) 一致.
A_TickCount

计算机自启动以来经过的毫秒数, 最多为 49.7 天. 通过把 A_TickCount 保存到变量中, 经过一段时间后从最近的 A_TickCount 值中减去那个变量, 可以计算出所经过的时间. 例如:

StartTime := A_TickCount
Sleep 1000
ElapsedTime := A_TickCount - StartTime
MsgBox ElapsedTime " milliseconds have elapsed."

如果您需要比 A_TickCount 的 10 ms 更高的精确度, 请使用 QueryPerformanceCounter()(一个高精度计时器).

脚本设置

dddddd
变量 描述
A_IsSuspended 如果脚本挂起时值为 1, 否则为 0.
A_IsPaused 如果在当前线程之后的线程暂停时值为 1, 否则为 0.
A_IsCritical如果当前线程Critical 是关闭时值为 0. 否则值为大于零的整数, 即为 Critical 使用的消息检查间隔. Critical 的当前状态可以通过 Old_IsCritical := A_IsCritical 然后是 Critical := Old_IsCritical 来保存和恢复.dddddd
A_ListLines 可用于获取或设置是否记录行. 可能的值是 0(禁用) 和 1(启用). 有关详情, 请参阅 ListLines.
A_TitleMatchMode 可用于获取或设置标题匹配模式. 可能的值是 1, 2, 3 和 RegEx. 有关详情, 请参阅 SetTitleMatchMode.
A_TitleMatchModeSpeed 可用于获取或设置标题匹配速度. 可能的值是 fast 和 slow. 有关详情, 请参阅 SetTitleMatchMode.
A_DetectHiddenWindows 可用于获取或设置是否检测隐藏窗口. 可能的值是 0(禁止) 和 1(启用). 有关详情, 请参阅 DetectHiddenWindows.
A_DetectHiddenText 可以用来获取或设置是否检测窗口中的隐藏文本. 可能的值是 0(禁止) 和 1(启用). 有关详情, 请参阅 DetectHiddenText.
A_FileEncoding 可以用来获取或设置各种内置函数的默认编码. 有关详情, 请参阅 FileEncoding.
A_SendMode 可用于获取或设置发送模式. 可能的值是 Event, Input, Play 和 InputThenPlay. 有关详情, 请参阅 SendMode.
A_SendLevel 可用于获取或设置发送级别, 为 0 至 100 之间的整数, 包括 0 和 100. 有关详情, 请参阅 SendLevel.
A_StoreCapsLockMode 可以用来获取或设置是否在 Send 后恢复 CapsLock 的状态. 可能的值是 0(禁止) 和 1(启用). 有关详情, 请参阅 SetStoreCapsLockMode.
A_KeyDelay
A_KeyDuration
可以用来获取或设置按键的延迟或持续时间, 单位为毫秒. 有关详情, 请参阅 SetKeyDelay.
A_KeyDelayPlay
A_KeyDurationPlay
可以用来获取或设置通过 SendPlay 模式发送的按键的延迟或持续时间, 单位为毫秒. 有关详情, 请参阅 SetKeyDelay.
A_WinDelay 可用于获取或设置窗口函数的延迟, 单位为毫秒. 有关详情, 请参阅 SetWinDelay.
A_ControlDelay 可用于获取或设置控件修改函数的延迟, 单位为毫秒. 有关详情, 请参阅 SetControlDelay.
A_MouseDelay
A_MouseDelayPlay
可以用来获取或设置鼠标延迟, 单位为毫秒. 传统的 SendEvent 模式为 A_MouseDelay, 而 SendPlay 为 A_MouseDelayPlay. 有关详情, 请参阅 SetMouseDelay.
A_DefaultMouseSpeed 可以用来获取或设置默认的鼠标速度, 从 0(最快) 到 100(最慢) 的整数. 有关详情, 请参阅 SetDefaultMouseSpeed.
A_CoordModeToolTip
A_CoordModePixel
A_CoordModeMouse
A_CoordModeCaret
A_CoordModeMenu
可以用来获取或设置相对坐标的区域. 可能的值是 Window, Client 或 Screen. 有关详情, 请参阅 CoordMode.
A_RegView 可用于获取或设置注册表视图. 可能的值是 32, 64 和 Default. 有关详情, 请参阅 SetRegView.
A_TrayMenu

返回可用于修改或显示托盘菜单的菜单对象.

A_AllowMainWindow

可以用来获取或设置是否允许通过托盘图标打开脚本的主窗口. 可能的值是 0(禁止) 和 1(允许).

如果脚本既不是编译的也不是嵌入的, 此变量默认为 1, 否则此变量默认为 0, 但可以通过给该变量赋值来改写它. 将其设置为 1 还可以恢复托盘菜单中的 "Open" 菜单项, 并启用主窗口的 View 菜单中的项目, 如 "Lines most recently executed", 这允许查看脚本的源代码和其他信息.

在脚本运行时遇到下列函数, 总是能够显示主窗口并选择相应的视图选项: ListLines, ListVars, ListHotkeysKeyHistory.

设置为 1 并不妨碍主窗口被 WinShow 显示, 或者被 ControlGetText 或类似的方法检查, 但它确实阻止了脚本的源代码和其他信息通过主窗口暴露出来, 除非脚本调用了上述的某个函数.

A_IconHidden 可以用来获取或设置是否隐藏托盘图标. 可能的值是 0(可见) 和 1(隐藏). 有关详情, 请参阅 #NoTrayIcon.
A_IconTip

可用于获取或设置托盘图标的工具提示文字, 当鼠标悬停在其上时显示该文本. 如果为空, 则使用脚本的名称.

要创建多行工具提示, 请在每行之间使用换行符(`n), 例如 "Line1`nLine2". 只显示前 127 个字符, 并且文本在第一个制表符(如果存在) 处被截断.

在 Windows 10 及更早版本中, 若要显示包含 & 符号的工具提示文本, 请使用另外两个 & 符号来转义 & 符号. 例如, 指定 A &&& B 将在工具提示的文本中显示 "A & B".

A_IconFile 如果通过 TraySetIcon 指定自定义的托盘图标时, 变量的值为图标文件的完整路径和名称, 否则为空.
A_IconNumber 如果 A_IconFile 为空时, 值为空. 否则, 它的值为 A_IconFile 中的图标的编号(通常为 1).

用户空闲时间

变量 描述
A_TimeIdle

从系统最后一次接收到键盘, 鼠标或其他输入后所经过的毫秒数. 这可以用来判断用户是否离开. 用户的物理输入和由 任何 程序或脚本生成的模拟输入(例如 SendMouseMove 函数) 会让此变量重置为零. 由于此变量的值趋向于以 10 的增量增加, 所以不应该判断它是否等于另一个值. 相反, 应该检查此变量是否大于或小于另一个值. 例如:

if A_TimeIdle > 600000
    MsgBox "The last keyboard or mouse activity was at least 10 minutes ago."
A_TimeIdlePhysical 与上面类似, 但在安装了相应的钩子(键盘鼠标) 后会忽略模拟的键击和/或鼠标点击; 即此变量仅对物理事件做出响应. (这样避免了由于模拟键击和鼠标点击而误以为用户存在.) 如果两种钩子都没有安装, 则此变量等同于 A_TimeIdle. 如果仅安装了一种钩子, 那么仅此类型的物理输入才会对 A_TimeIdlePhysical 起作用(另一种/未安装钩子的输入, 包括物理的和模拟的, 都会被忽略).
A_TimeIdleKeyboard 如果安装了键盘钩子, 这是自系统上次接收物理键盘输入以来所经过的毫秒数. 否则, 这个变量就等于 A_TimeIdle.
A_TimeIdleMouse 如果安装了鼠标钩子, 这是自系统上次收到物理鼠标输入以来所经过的毫秒数. 否则, 这个变量就等于 A_TimeIdle.

热键, 热字串和自定义菜单项

变量 描述
A_ThisHotkey

最近执行的热键非自动替换热字串(如果没有则为空), 例如 #z. 如果当前线程被其他热键或热字串中断, 那么此变量的值会变化, 所以一般情况下, 最好使用 ThisHotkey 参数.

首次创建热键时 -- 通过 Hotkey 函数或脚本中的双冒号语法 -- 其键名及其修饰符的顺序成为此热键的固定名称, 由热键的所有变体共享.

首次创建热字串时 -- 通过 Hotstring 函数或脚本中的双冒号标签 -- 它的触发字符串和选项字符序列成为该热字符串的永久名称.

A_PriorHotkey 除了保存前一次热键的名称外, 其他的与上面相同. 如果没有它会为空.
A_PriorKey 在最近一次键-按下或键-释放之前按下的最后一个键的名称, 如果在按键历史中找不到合适的键-按下则为空. 不包括由 AutoHotkey 脚本生成的所有输入. 要使用此变量, 首先必须安装键盘鼠标钩子并且启用了key history(按键历史).
A_TimeSinceThisHotkey 从 A_ThisHotkey 按下后到现在经过的毫秒数. 如果 A_ThisHotkey 为空, 则此变量的值为空.
A_TimeSincePriorHotkey 从 A_PriorHotkey 按下后到现在经过的毫秒数. 如果 A_PriorHotkey 为空, 则此变量的值为 -1.
A_EndChar 用户最近按下的触发了非自动替换热字串终止字符. 如果不需要终止符(由于使用了 * 选项), 那么此变量将为空.
A_MaxHotkeysPerInterval 可用于获取或设置在 A_HotkeyInterval 所定义的时间间隔内按下热键而不会触发警告对话框的最大数量. 有关详情, 请参阅 A_MaxHotkeysPerInterval.
A_HotkeyInterval 可用于获取或设置 A_MaxHotkeysPerInterval 使用的时间间隔长度, 以毫秒为单位.
A_HotkeyModifierTimeout 可用于获取或设置超时, 该超时影响带有以下热键修饰符的 Send 的行为: Ctrl, Alt, WinShift. 有关详情, 请参阅 A_HotkeyModifierTimeout.

操作系统和用户信息

变量 描述
A_ComSpec

包含与 ComSpec 环境变量相同的字符串, 通常是命令提示符可执行文件(cmd.exe) 的完整路径. 常与 Run/RunWait 一起使用. 例如:

C:\Windows\system32\cmd.exe
A_Temp

存放临时文件的文件夹的完整路径和名称. 它的值从下列的其中一个位置检索(按顺序): 1) 环境变量 TMP, TEMP 或 USERPROFILE; 2) Windows 目录. 例如:

C:\Users\<UserName>\AppData\Local\Temp
A_OSVersion

操作系统的版本号, 格式为 "major.minor.build". 例如, Windows 7 SP1 为 6.1.7601.

在 AutoHotkey 可执行文件或已编译脚本的属性中应用兼容性设置会导致系统报告不同的版本号, 这将体现在 A_OSVersion 中.

A_Is64bitOS 当操作系统为 64 位则值为 1(true), 为 32 位则为 0(false).
A_PtrSize 包含指针的大小值, 单位为字节. 值为 4(32 位) 或 8(64 位), 取决于运行当前脚本的执行程序的类型.
A_Language 当前系统的默认语言, 值为这些 4 位数字编码的其中一个.
A_ComputerName 在网络上看到的计算机名称.
A_UserName 运行当前脚本的用户的登录名.
A_WinDir Windows 目录. 例如: C:\Windows
A_ProgramFiles

Program Files 目录(例如 C:\Program FilesC:\Program Files (x86)). 这通常与 ProgramFiles 环境变量相同.

64-位系统(和非 32-位系统), 适用于下列内容:

  • 如果可执行文件(EXE) 以 32 位脚本运行的时候, A_ProgramFiles 返回路径为 "Program Files (x86)" 目录.
  • 对于 32 位的进程, ProgramW6432 环境变量指向 64 位 Program Files 目录的路径. 在 Windows 7 和更高版本上, 对于 64 位的进程也是这样设置的.
  • ProgramFiles(x86) 环境变量指向 32 位 Program Files 目录的路径.
A_AppData

当前用户的应用程序数据文件夹的完整路径和名称. 例如:

C:\Users\<UserName>\AppData\Roaming
A_AppDataCommon

所有用户的应用程序数据文件夹的完整路径和名称. 例如:

C:\ProgramData
A_Desktop

当前用户的桌面文件夹的完整路径和名称. 例如:

C:\Users\<UserName>\Desktop
A_DesktopCommon

所有用户的桌面文件夹的完整路径和名称. 例如:

C:\Users\Public\Desktop
A_StartMenu

当前用户的开始菜单文件夹的完整路径和名称. 例如:

C:\Users\<UserName>\AppData\Roaming\Microsoft\Windows\Start Menu
A_StartMenuCommon

所有用户的开始菜单文件夹的完整路径和名称. 例如:

C:\ProgramData\Microsoft\Windows\Start Menu
A_Programs

当前用户的开始菜单中程序文件夹的完整路径和名称. 例如:

C:\Users\<UserName>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
A_ProgramsCommon

所有用户的开始菜单中程序文件夹的完整路径和名称. 例如:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs
A_Startup

当前用户的开始菜单中启动文件夹的完整路径和名称. 例如:

C:\Users\<UserName>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
A_StartupCommon

所有用户的开始菜单中启动文件夹的完整路径和名称. 例如:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
A_MyDocuments

当前用户 "我的文档" 文件夹的完整路径和名称. 与大多数类似变量不同, 当此文件夹为驱动器的根目录时, 此变量的值不包含最后的反斜杠(例如, 它的值是 M: 而不是 M:\). 例如:

C:\Users\<UserName>\Documents
A_IsAdmin

如果当前用户有管理员权限, 则值为 1, 否则为 0.

要使脚本以管理员权限重新启动(或显示提示向用户请求管理员权限), 请使用 Run *RunAs. 但是请注意, 以管理员权限运行脚本会导致脚本启动的所有程序也以管理员权限运行. 对于可能的替代方案, 请参阅常见问题(FAQ).

A_ScreenWidth
A_ScreenHeight

主监视器的宽度和高度, 单位为像素(例如 1024 和 768).

要获取多显示器系统中其他显示器的尺寸, 请使用 SysGet.

要获取整个桌面(即使它横跨多个显示器) 的宽度和高度, 请使用下面的例子:

VirtualWidth := SysGet(78)
VirtualHeight := SysGet(79)

此外, 使用 SysGet 可以获取显示器的工作区域, 它比显示器的整个区域小, 因为它不包括任务栏和其他注册的桌面工具栏.

A_ScreenDPI 沿屏幕宽度每逻辑英寸的像素数. 在具有多个显示监视器的系统中, 此值对于所有监视器都是相同的. 在大多数系统中该值为 96; 它取决于系统文本大小(DPI) 设置. 另请参阅 GUI 的 -DPIScale 选项.

杂项

变量 描述
A_Clipboard 可用于获取或设置系统剪贴板的内容. 有关详情, 请参阅 A_Clipboard.
A_Cursor

当前显示的鼠标光标类型. 其值为下列单词的其中一个: AppStarting(程序启动, 后台运行--箭头+等待), Arrow(箭头, 正常选择--标准光标), Cross(十字, 精确选择), Help(帮助, 帮助选择--箭头+问号), IBeam(工字光标, 文本选择--输入), Icon, No(No, 不可用--圆圈加反斜杠), Size, SizeAll(所有尺寸, 移动--四向箭头), SizeNESW(东南和西北尺寸, 沿对角线调整 2--双箭头指向东南和西北), SizeNS(南北尺寸, 垂直调整--双箭头指向南北), SizeNWSE(西北和东南尺寸, 沿对角线调整 1--双箭头指向西北和东南), SizeWE(东西尺寸, 水平调整--双箭头指向东西), UpArrow(向上箭头, 候选--指向上的箭头), Wait(等待, 忙--沙漏或圆圈), Unknown(未知). 与 size-类型光标一起使用的缩略词是罗盘方向, 例如 NESW = NorthEast(东北)+SouthWest(西南). 手型指针(点击和抓取) 属于 Unknown 类别.

A_EventInfo

包含下列事件的额外信息:

注意: 与类似 A_ThisHotkey 这样的变量不同, 每个线程保留自身的 A_EventInfo 值. 因此, 如果一个线程被另一个中断, 在这个线程恢复时它仍将看到这些变量的原来/正确的值.

脚本也可以设置 A_EventInfo, 但只能在指针可用的范围内接受无符号整数(32-bit 或 64-bit 取决于 AutoHotkey 的版本).

A_LastError

这通常是脚本调用某些函数后, 包括 DllCall, Run/RunWait, File/Ini/Reg 函数(在文档中) 和可能的其他函数, 系统 GetLastError() 函数的结果. A_LastError 是一个介于 0 和 4294967295 之间的数字(通常格式化为十进制, 而不是十六进制). 零(0) 表示成功, 但是任何其他数字都表示调用失败. 每个数字对应一个特定的错误条件. 要了解如何获得本地化的错误描述文本, 请参阅 OSError, 或在 www.microsoft.com 搜索 "系统错误代码", 以获得列表. A_LastError 是每个线程的设置; 也就是说, 被其他线程中断不能改变它.

给 A_LastError 赋值, 也会调用系统的 SetLastError() 函数.

True
False

包含 1 和 0. 它们可以用来使脚本更具可读性. 有关详情, 请参阅布尔值.

这些实际上是关键字, 而不是变量.

Loop

变量 描述
A_Index 可用于获取或设置当前循环迭代的次数(64 位整数). 第一次循环体执行时, 它为 1. 第二次, 它的值为 2; 依次类推. 如果一个内循环被外循环包围, 那么内循环优先. A_Index 在所有类型的循环中都起作用, 但在循环语句外值为 0. 对于像 Loop 这样的计数循环, 更改 A_Index 会影响将要执行的迭代次数.
A_LoopFileName, 等 此变量和其他相关变量仅在文件循环中有效.
A_LoopRegName, 等 此变量和其他相关变量仅在注册表循环中有效.
A_LoopReadLine 请参阅文件读取循环.
A_LoopField 请参阅解析循环.

变量的容量和占用内存