# 程序的使用

AutoHotkey 程序本身不做任何事情; 它需要一个脚本来告诉它该做什么. 脚本只是一个简单的以 `.ahk` 作为扩展名的文本文件, 其中包含了程序的指令, 像配置文件, 但功能更强大. 一个脚本可以执行一个动作然后退出, 但大多数脚本定义了一些热键, 当热键按下时, 热键后面跟着的一个或多个动作将会执行.

    #z::Run "https://www.autohotkey.com"  ; Win+Z

    ^!n::  ; Ctrl+Alt+N
    {
        if WinExist("Untitled - Notepad")
            WinActivate
        else
            Run "Notepad"
    }

提示: 如果您的浏览器支持, 当你将鼠标悬停在代码块上面时, 您可以通过点击代码块右上角的按钮来下载任何代码块(如上面的代码块) 作为脚本文件.

## 目录

- 创建脚本
- 编辑脚本
- 运行脚本
- 托盘图标
- 主窗口
- 嵌入脚本
- 命令行用法
- AutoHotkey.exe 的可移植性
- 启动器
- Dash
- 新建脚本
- 安装
  - 以 UI 访问权限运行

## 创建脚本

有一些常见的方法来创建脚本文件:

- 在记事本(或你选择的文本编辑器) 中, 使用 `.ahk` 文件扩展名保存文件. 在某些系统上, 您可能需要将文件名用引号括起来, 以确保编辑器不会添加其他扩展名(例如 .txt).

  如果文件包含非 ASCII 字符, 请确保将文件保存为带有 BOM(字节顺序标记) 的 UTF-8. 有关详情, 请参阅常见问题(FAQ).

- 在资源管理器, 希望保存脚本的文件夹中的空白区域右键单击, 然后选择 新建 和 AutoHotkey Script. 然后, 您可以输入脚本的名称(注意, 如果 `.ahk` 扩展名可见时, 请不要删掉它).
- 在 Dash, 选择 New script, 为脚本输入名称(不包括 `.ahk` 扩展名), 然后单击 Create 或 Edit. 可以在此窗口中配置用于创建脚本的模板和保存脚本的位置, 并根据需要将其设置为默认值.

有关如何编写脚本的详细信息, 请参阅脚本语言.

## 编辑脚本

要打开脚本进行编辑, 请右键单击脚本文件, 然后选择 Edit Script(编辑脚本). 如果脚本已经在运行, 您可以使用 Edit(编辑) 函数或右键单击脚本的托盘图标并选择 Edit Script(编辑脚本). 如果您还没有选择默认编辑器, 系统将提示您选择一个. 否则, 您可以在 Dash 中通过 Editor settings 更改默认编辑器. 当然, 您可以先打开文本编辑器, 然后像打开其他任何文本文件一样打开脚本.

编辑脚本保存后, 您必须运行或 reload(重新加载) 脚本以使更改生效. 正在运行的脚本通常可以通过其托盘菜单重新加载.

## 运行脚本

安装了 AutoHotkey 后, 有几种运行脚本的方法:

- 双击资源管理器中的脚本文件(或脚本文件的快捷方式).
- 在命令行中调用 AutoHotkey.exe, 并将该脚本的文件名(路径) 作为命令行参数.
- 创建默认脚本后, 通过 "开始" 菜单中的快捷方式启动 AutoHotkey 以运行它.
- 如果 AutoHotkey 固定在 Windows 7 或更高版本系统的任务栏或 "开始" 菜单上, 则可以通过程序跳转列表打开最近的或已固定的脚本.

大多数脚本只有在运行时才会起作用. 使用托盘菜单或 ExitApp 函数退出脚本. 当 Windows 关闭时, 脚本也被迫退出. 要将脚本配置为在用户登录后自动启动, 最简单的方法是在 Startup(启动) 文件夹中放置脚本文件的快捷方式.

脚本也可以编译; 即与 AutoHotkey 二进制文件结合在一起, 形成一个独立的可执行(.exe) 文件.

## 托盘图标

默认情况下, 每个脚本都将自己的图标添加到任务栏通知区域(通常称为托盘).

托盘图标通常看起来像这样:

| 默认的托盘图标.
| 脚本暂停.
| 脚本挂起.
| 脚本暂停和挂起.

右键单击托盘图标以显示托盘菜单, 默认情况下具有以下选项:

- Open - (打开) - 打开脚本的主窗口.
- Help - (帮助) - 打开 AutoHotkey 离线帮助文件.
- Window Spy - (窗口监视器) - 显示关于窗口的各种信息.
- Reload Script - (重载脚本) - 请参阅 Reload.
- Edit Script - (编辑脚本) - 请参阅 Edit.
- Suspend Hotkeys - (挂起热键) - Suspend 或取消挂起热键.
- Pause Script - (暂停脚本) - Pause 或取消暂停脚本.
- Exit - (退出) - 退出脚本.

默认情况下, 双击托盘图标显示脚本的主窗口.

可以自定义托盘图标和菜单的行为和外观:

- A_TrayMenu 返回 Menu 对象, 可以用来自定义托盘菜单.
- A_IconHidden 或 #NoTrayIcon 指令可用于隐藏(或显示) 托盘图标.
- A_IconTip 可以为托盘图标分配新的工具提示文本.
- TraySetIcon 可以用来改变图标.

## 主窗口

脚本的主窗口通常是隐藏的, 但可以通过托盘图标或下面列出的函数之一显示, 以获得对调试脚本有用的信息. View 菜单下的项目控制主窗口显示的内容:

- Lines most recently executed - (最近执行的行) - 请参阅 ListLines.
- Variables and their contents - (变量和它们的内容) - 请参阅 ListVars.
- Hotkeys and their methods - (热键和它们的方法) - 请参阅 ListHotkeys.
- Key history and script info - (按键历史和脚本信息) - 请参阅 KeyHistory.

已知问题: 当脚本显示消息框或其他对话框时, 菜单项下的键盘快捷键不起作用.

内置变量 A_ScriptHwnd 包含脚本主窗口的唯一 ID(HWND).

用 WinClose(甚至从另一个脚本或其他程序) 关闭这个窗口会导致脚本退出, 但大多数其他方法只是隐藏窗口并保持脚本运行.

最小化主窗口会使其自动隐藏. 这样做是为了防止将所有拥有的窗口(如 GUI 窗口或某些对话框窗口) 自动最小化, 但也有隐藏主窗口的任务栏按钮的效果. 要让主窗口正常最小化, 可以用 OnMessage 覆盖默认的处理方式. 例如:

    ; 这样可以防止主窗口在最小化时隐藏:
    OnMessage 0x0112, PreventAutoMinimize ; WM_SYSCOMMAND = 0x0112
    OnMessage 0x0005, PreventAutoMinimize ; WM_SIZE = 0x0005
    ; 这样可以防止拥有的 GUI 窗口(但不包括对话框) 自动最小化:
    OnMessage 0x0018, PreventAutoMinimize
    Persistent

    PreventAutoMinimize(wParam, lParam, uMsg, hwnd) {
        if (uMsg = 0x0112 && wParam = 0xF020 && hwnd = A_ScriptHwnd) { ; SC_MINIMIZE = 0xF020
            WinMinimize
            return 0 ; 防止主窗口隐藏.
        }
        if (uMsg = 0x0005 && wParam = 1 && hwnd = A_ScriptHwnd) ; SIZE_MINIMIZED = 1
            return 0 ; 防止主窗口隐藏.
        if (uMsg = 0x0018 && lParam = 1) ; SW_PARENTCLOSING = 1
            return 0 ; 防止最小化拥有的窗口.
    }

### 主窗口标题

脚本主窗口的标题会被 #SingleInstance 和 Reload 机制用来识别同一脚本的其他实例. 更改标题可防止脚本被这样识别. 默认的标题取决于脚本的加载方式:

加载于 | 标题表达式 | 示例
--- | --- | ---
.ahk 文件 | `A_ScriptFullPath " - AutoHotkey v" A_AhkVersion` | E:\My Script.ahk - AutoHotkey v1.1.33.09
主资源(编译的脚本) | `A_ScriptFullPath` | E:\My Script.exe
任何其他资源 | `A_ScriptFullPath " - " A_LineFile` | E:\My AutoHotkey.exe - *BUILTIN-TOOL.AHK

下面的代码说明了如何由脚本本身决定默认的标题(但实际的标题可以用 WinGetTitle 来检索):

    title := A_ScriptFullPath
    if !A_IsCompiled
        title .= " - AutoHotkey v" A_AhkVersion
    ; 为了获得正确的结果, 必须由被执行的资源来计算,
    ; 而不是一个 #include(除非这个 #include 是由 Ahk2Exe 合并到脚本中的):
    else if SubStr(A_LineFile, 1, 1) = "*" && A_LineFile != "*#1"
        title .= " - " A_LineFile

## 嵌入脚本

通过使用 Ahk2Exe 编译器, 可以将脚本嵌入到标准的 AutoHotkey 的 .exe 文件, 方法是将它们作为 Win32(RCDATA) 资源来添加. 要添加其他脚本, 请参阅 AddResource 编译器指令.

嵌入的脚本可以在命令行中指定, 也可以使用 #Include 在星号(*) 后跟资源名称. 对于一个整数 ID, 资源名称必须是一个哈希符号(#), 后面是一个十进制数字.

程序可以自动从以下资源加载脚本代码, 如果存在于文件中:

ID | Spec | 用法
--- | --- | ---
1 | *#1 | 这是一种从 .exe 文件创建编译脚本的方法. 该脚本是自动执行的, 大多数命令行开关会被传递给脚本, 而不是由程序解释. 外部脚本和可选的嵌入式脚本可以通过使用 /script 开关来执行.
2 | *#2 | 如果存在, 该脚本会在程序加载的任何脚本之前自动 "included", 以及在 /include 指定的任何文件之前.

当主脚本的源是一个嵌入式资源时, 程序以 "编译脚本" 模式运行, 但 A_AhkPath 总是包含当前可执行文件的路径(与 A_ScriptFullPath 相同). 对于 *#1 以外的资源, 资源指定符会包含在主窗口的标题中, 以支持 #SingleInstance 和 Reload.

当从嵌入资源的代码中引用时, A_LineFile 包含一个星号(*) 后跟资源名称.

## 命令行用法

有关命令行用法, 请参阅向脚本传递命令行参数, 其中包括影响程序行为的命令行开关列表.

## AutoHotkey.exe 的可移植性

运行任何的 .ahk 脚本所需要的只是 AutoHotkey.exe 文件.

重命名 AutoHotkey.exe 会同时改变它默认运行的脚本, 这是在没有安装 AutoHotkey 的计算机上运行脚本的一种可选方法. 例如, 在没有指定文件名时, 执行 MyScript.exe 会自动运行 MyScript.ahk, 但也能运行其他脚本.

## 启动器

启动器可以在一个系统上使用 v1 和 v2 版本的脚本, 并使用一个文件扩展名, 而不必偏好一个版本, 也不需要用不同的方法来启动脚本. 它通过检查脚本以找到所需版本的线索, 然后定位一个适当的 exe 来运行脚本.

如果脚本包含 #Requires 指令, 启动器将寻找满足需求的 exe. 否则, 启动程序可选地检查语法. 也就是说, 它检查只在两个主要版本之一中有效的模式. 它可能发现的一些常见模式包括:

- v1: `MsgBox, with comma`, `MsgBox % "no end percent"` 和 `Legacy = assignment`.
- v1: 没有大括号或函数定义的多行热键.
- 常见指令如 #NoEnv 和 #If(v1) 或 #HotIf(v2).
- v2: 通过括号延续或行末延续操作符明确使用行延续.
- v2: 在表达式中明确使用 `'单引号'` 或 胖箭头 `=>`.

检测是保守的; 如果一个案例是模棱两可的, 通常应该被忽略.

在任何检测失败的情况下, 默认会显示一个菜单让用户选择一个版本. 这个默认值可以改变为启动 v1 或 v2.

已知限制:

- 只检查主文件.
- 由于在 v1 中包含像 `/****/` 这样的行是合法的, 但在 v2 中行尾的 `*/` 只能关闭注释, 所以这样的行的存在可能会导致脚本的大部分被忽略(被启动器和 v1 解释器忽略).
- 只检查语法, 不检查语义. 例如, `xyz,` 在 v2 中是无效的, 所以被认为是有效的 v1 命令. `xyz 1` 在 v2 中可能是一个函数语句, 但被认为也是有效的 v1 命令, 因此被忽略.
- 由于被检测到的模式实际上是一个版本中的语法错误, 一个有实际语法错误或不正确的混合语法的脚本可能被错误地识别出来.

注意: 在主文件的顶部用 #Requires 声明所需的版本, 可以消除任何歧义.

### 启动设置

启动器可以通过启动设置GUI来启用、禁用或配置，该GUI可以通过dash访问 dash.

使用特定的解释器运行所有脚本 将禁用启动程序, 并允许用户选择使用哪个 exe 来运行所有脚本, 这是传统的方式. 请注意, 选择 v1 exe 将使其难以运行任何支持脚本, 除非通过开始菜单中的 "AutoHotkey" 快捷方式.

启动脚本时的自动检测版本 将激活启动器. 其他设置可以控制启动器如何选择要使用的解释器.

### Criteria

当找到具有相同版本号的多个解释器时, 启动器可以根据预先确定的或用户定义的一组条件对它们进行排序. 这些条件可以表示为以逗号分隔的子字符串列表, 其中每个子字符串可以用 "!" 作为前缀来否定匹配. 根据匹配的子串来计算得分, 最左边的子串具有最高的优先级.

子字符串在文件的描述中匹配, 但 "UIA" 除外, 如果文件名包含 "_UIA", 则匹配.

例如, `_H, 64, !ANSI` 倾向于 AutoHotkey_H(如果可用), 64-位(如果与系统兼容), 最后是 Unicode 而不是 ANSI.

尽管启动器设置 GUI 提供带有选项的下拉列表, 如 "Unicode 32-bit", 但可以手动输入子字符串列表.

可以使用 /RunWith 启动器开关在命令行上指定其他(更高优先级的) 条件.

可以在脚本中使用 #Requires 指令指定条件, 可以作为需求(如果目标 AutoHotkey 版本支持), 也可以作为以 "prefer" 开头, 以句号或行尾结尾的注释添加到指令中. 例如:

    #Requires AutoHotkey v1.1.35 ; prefer 64-bit, Unicode. 更多的注释内容.

### Run *Launch

安装程序注册一个名为 "launch" 的隐藏 shell 动词, 它使用 /Launch 开关执行启动程序. 它可以通过以下示例使用:

    pid := RunWait('*Launch "' PathOfScript '"')

与 .ahk 文件的默认操作相比:

- /Launch 导致新启动脚本的进程 ID(PID) 作为启动器的退出码返回, 而通常情况下, 它会返回启动脚本的退出码. Run 的 OutputVarPID 参数返回启动器的 PID.
- /Launch 使启动器在启动脚本后立即退出. 如果没有使用 /Launch, 启动器通常必须假定它的父进程可能正在执行 `RunWait(PathOfScript)` 之类的操作, 如果启动器在启动脚本之前退出, 将无法正常工作.

### 命令行用法

如果 .ahk 文件没有默认设置使用启动程序, 或者为了更好地控制其行为, 可以在命令行显式地执行启动程序. 如果编译了启动程序, 它的用法基本上与 AutoHotkey.exe 相同, 除了附加的启动程序开关. 否则, 命令行使用格式如下:

    AutoHotkeyUX.exe launcher.ahk [Switches] [Script Filename] [Script Parameters]

通常, AutoHotkeyUX.exe 和 launcher.ahk 的路径使用全路径和双引号, 可以在 AutoHotkey 安装的 UX 子目录中找到. 一个适当版本的 AutoHotkey32.exe 或 AutoHotkey64.exe 可以用来代替 AutoHotkeyUX.exe(这只是一个副本).

Switches 可以是任何标准开关和以下启动器专用开关的混合:

开关 | 意义
--- | ---
/Launch | 导致启动器在启动脚本后立即退出, 而不是在后台等待它终止. 启动器的退出代码是新脚本进程的进程 ID(PID).
/RunWith criteria | 指定用于确定要使用哪个可执行文件来启动脚本的附加 criteria. 例如, `/RunWith UIA`.
/Which | 使启动器识别它将使用的解释器并返回它, 而不是运行脚本. 如果由 #Requires 或语法(如果启用了语法检测) 标识, 启动器的退出代码是主版本号(1 或 2), 否则为 0. Stdout 接收以下 UTF-8 字符串, 每个字符串以 ``n` 结尾: 版本号. 如果检测到 #Requires, 则这是它指定的任何数字, 不包括 "v". 否则, 它是一个与退出码相同的整数, 除非没有检测到版本, 在这种情况下, 该值为 0 表示用户会被提示, 1 或 2 表示在 Launch Settings 中配置的用户首选版本. 如果找到解释器 EXE, 将使用的解释器 EXE 的路径. 如果用户被提示或没有找到兼容的解释器, 则此选项为空. 启动器将插入的任何额外的命令行开关, 如 `/CP65001`. 将来可能会返回更多的行.

## Dash

Dash 提供了对支持脚本和文档的访问. 它可以在安装后通过开始菜单中的 "AutoHotkey" 快捷方式打开, 或从安装目录 UX\ui-dash.ahk 直接运行. 目前它仅仅是一个包含以下项目的菜单, 但是它可以扩展为活动脚本或其他方便的功能提供控制.

- New script(新建脚本): 从模板创建新脚本.
- Compile(编译): 打开 Ahk2Exe, 或提供自动下载和安装它.
- Help files (F1) (帮助文件): 显示一个菜单, 其中包含关于 v1 和 v2 的帮助文件和在线文档, 以及安装目录中找到的任何其他 CHM 文件.
- Window spy
- Launch settings(启动设置): 配置启动器.
- Editor settings(编辑设置): 设置 .ahk 文件的默认编辑器.

注意, 尽管开始菜单快捷方式启动了 Dash, 如果它被固定在任务栏上(或在Windows 7或10的开始菜单上), 跳转列表将包括任何最近使用 open, runas 或 UIAccess 动词启动的脚本(通常通过资源管理器上下文菜单或双击文件来访问). 可以固定脚本以便于访问.

## 新建脚本

新建脚本 GUI 可以通过开始菜单中的 Dash 访问, 也可以在资源管理器中的文件夹中右键单击并选择新建 → AutoHotkey Script. 可以使用它从预先安装的或用户定义的模板创建一个新的脚本文件, 并可选择打开它进行编辑.

在列表中右键点击一个模板, 可以得到以下选项:

- Edit template(编辑模板): 在默认编辑器中打开模板. 如果是预安装的模板, 则创建一个可编辑的副本, 而不是打开原始的.
- Hide template(隐藏模板): 将模板名称添加到一个模板列表中, 该模板将不会显示在 GUI 中. 要取消隐藏模板, 请从 `HKCU\Software\AutoHotkey\New\HideTemplate` 中删除对应的注册表值.
- Set as default(设置为默认值): 设置默认选择的模板.

默认情况下, 除非按住 Ctrl 键，否则 GUI 会在创建文件后关闭.

其他设置可以通过 GUI 左下角的设置按钮来访问:

- Default to Create(默认创建): 按 Enter 将激活 Create 按钮, 创建脚本并在资源管理器中选择它.
- Default to Edit(默认编辑): :按 Enter 将激活 Edit 按钮, 这将创建脚本并在默认脚本编辑器中打开它.
- Stay open(保持打开): 如果启用, 创建脚本后窗口不会自动关闭.
- Set folder as default(设置文件夹为默认): 将当前文件夹设置为脚本的默认保存位置. 如果新建脚本窗口直接打开或通过 Dash 打开, 则使用默认位置; 当通过资源管理器上下文菜单调用新脚本时不使用它.
- Open templates folder(打开模板文件夹): 打开存放用户定义模板的文件夹.

### 模板

模板文件从 UX\Templates (预安装的) 和 %A_MyDocuments%\AutoHotkey\Templates (用户自定义的) 中绘制, 使用用户定义的模板覆盖任何具有相同名称的预安装模板. 如果一个文件存在于 %A_WinDir%\ShellNew\Template.ahk, 它被显示为 "Legacy", 可以被用户定义的同名模板覆盖.

每个模板可以包含一个 INI 节, 如下所示:

    /*
    [NewScriptTemplate]
    Description = Descriptive text
    Execute = true|false|1|0
    */

如果如上面所示, INI 节以 `/*` 开始, 而以 `*/` 结束, 则它不包含在创建的文件中.

Description(描述) 是可选的. 除了文件名之外, 该项也显示在 GUI 中.

Execute(执行) 是可选的. 如果设置为 true, 执行模板脚本时 `A_Args[1]` 包含要创建的文件的路径, 而 `A_Args[2]` 包含 "Create" 或 "Edit", 这取决于用户单击的是哪个按钮. 模板脚本将创建文件并打开它进行编辑(如果适用的话). 如果模板脚本需要 `#include` 其他文件, 可以将它们放在子目录中, 以避免在模板列表中显示它们.

## 安装

这个安装程序和相关的脚本是为了允许多个版本的 AutoHotkey 共存. 安装程序提供的选项非常少, 因为大多数东西都可以在安装后进行配置. 只有以下选择必须在安装过程中做出:

- 安装在哪里.
- 是为所有用户还是为当前用户安装.

默认情况下, 安装程序将为所有用户安装到 "%A_ProgramFiles%\AutoHotkey". 这是推荐的, 因为 UI Access 选项要求程序安装在 Program Files 下. 如果安装程序还没有以管理员身份运行, 当点击安装按钮时, 它将尝试提升权限, 如按钮上的盾牌图标所显示的.

当前用户的安装不需要管理员权限，只要用户有对所选目录的写入权限。当前用户安装的默认目录是 "%LocalAppData%\Programs\AutoHotkey".

### 与 v1 同时安装

同时安装 v1 和 v2, 有两种方式:

1. 首先安装 v1, 然后安装 v2. 在这种情况下, v1 的文件被留在安装目录的根部, 以避免破坏任何依赖其当前路径的外部工具或快捷方式.
2. 将 v1 作为一个额外的版本来安装. 运行 v1.1.34.03 或更高版本的安装程序会有这个选项. 或者, 使用下面描述的 `/install` 开关. 每个版本都会安装到它自己的子目录中.

运行 v1.1.34.02 或更早的安装程序(或使用 v1.1.34.03 或更新的自定义安装程序) 将覆盖 v2 安装程序在注册表中设置的一些值, 如版本号, 卸载程序条目和文件类型注册的部分. 它还会注册 v1 版的卸载程序, 该程序无法正确卸载两个版本. 要重新注册 v2, 请重新运行任何 v2 安装程序或使用 AutoHotkey32.exe 或 AutoHotkey64.exe 运行 UX\install.ahk.

### 默认版本

与 v1 安装不同, 在安装期间不会选择默认版本. 缺省值由启动器更动态地处理, 并且可以为每个用户配置.

### 使用命令行

要从源目录中直接安装到 DESTINATION 目录, 请使用下面展示的 `/installto` 或 `/to`(这两个开关可以互换). 使用下载的 setup.exe 或从下载的 zip 或其他来源中提取的文件.

    AutoHotkey_setup.exe /installto "%DESTINATION%"

    AutoHotkey32.exe UX\install.ahk /to "%DESTINATION%"

要从 SOURCE(目录中应该有 AutoHotkey*.exe 文件) 安装额外的版本, 请在当前安装目录中执行以下命令(根据需要调整 AutoHotkey32.exe 的路径):

    AutoHotkey32.exe UX\install.ahk /install "%SOURCE%"

上面的完整命令字符串在 under `HKLM\Software\AutoHotkey` 或 `HKCU\Software\AutoHotkey` 下 InstallCommand 注册, 其中 `%1` 作为源目录的替代. 使用这个注册表值可能更具有前瞻性.

重新注册当前安装:

    AutoHotkey32.exe UX\install.ahk

卸载:

    AutoHotkey32.exe UX\install.ahk /uninstall

或者, 从以下注册表键中读取 QuietUninstallString 值, 并执行它:

    HKLM\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey
    HKCU\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey

使用 `/silent` 开关来抑制警告或确认对话框, 并防止在安装完成时显示 Dash. 以下操作可能会自动执行, 而且没有警告:

- 终止脚本以允许 AutoHotkey*.exe 被覆盖.
- 覆盖安装程序以前没有注册的文件, 或注册后修改的文件.

### 任务栏按钮

v2 安装程序没有提供分离任务栏按钮的选项. 以前, 这是通过将每个 AutoHotkey 可执行文件注册为宿主程序(IsHostApp) 来实现的, 但这种方法有局限性, 当安装多个版本时, 就变得不容易管理. 作为替代, 每个脚本应该设置其进程或窗口的 AppUserModelID 来控制分组.

### 以 UI Access 运行

当安装在 Program Files 时, 安装程序会创建一组额外的 AutoHotkey exe 文件, 可用于解决一些常见的 UAC 相关问题. 这些文件以 "_UIA.exe" 为后缀. 当管理员使用这些 UIA.exe 文件中的一个来运行脚本时, 脚本能够与以管理员权限运行的程序的窗口进行交互, 而不需要脚本本身以管理员权限来运行.

安装程序执行如下操作:

- 复制每个 AutoHotkey*.exe 为 AutoHotkey*_UIA.exe.
- 在每个 UIA 文件的嵌入式清单(manifest) 中设置 uiAccess 属性.
- 创建名为 "AutoHotkey" 的自签名数字证书, 然后签名每个 UIA 文件.
- 注册 UIAccess 外壳动词, 在资源管理器的上下文菜单中显示为 "Run with UI access"(以 UI 权限运行). 默认情况下, 这会执行启动器, 它会尝试选择一个适当的 UIA.exe 文件来运行脚本.

启动器也可以配置为默认情况下使用 UI 权限运行 v1 脚本, v2 脚本或两者, 但如果所选版本和构建不存在 UIA.exe 文件, 则此选项无效.

脚本需要其他脚本以 UI 权限运行, 可以简单地 Run(运行) 对应的 UIA.exe 文件加上正常的命令行参数. 另外, 如果注册了 UIAccess 外壳动词, 它可以通过 Run 使用. 例如: `Run '*UIAccess "Script.ahk"'`

已知限制:

- UIA 只会影响信任区域的文件; 比如 Program Files 的子目录.
- 如果没有注册程序发布者用于签名的数字证书, 那么 UIA.exe 文件不能在其他计算机上运行.
- 由于安全限制, UIA.exe 文件无法通过 CreateProcess 启动. 不过可以用 ShellExecute 替代. 内置的 Run 命令将会自动尝试以这两种方式运行.
- UIA.exe 文件不可修改, 否则无法通过文件的数字签名验证.
- 由于 UIA 程序和其他程序具有不同的 "integrity level(可信级别)", 它们仅可通过其他的 "UIA 程序" 来注册对象. 比如, `ComObjActive("Word.Application")` 将会失败, 因为 Word 并不是一个 UI Access 标记的程序.
- 由于安全限制, 脚本自身的窗口无法自动视为 "无 UIA 程序或脚本".
- 运行使用鼠标钩子的 "非 UIA 脚本" 时(类似简单的出现了 `InstallMouseHook` 指令), 鼠标热键会在由 UIA 脚本创建的窗口中失效, 即使热键为 "UIA 脚本" 自身定义的. 可行的解决办法是: 确保 "UIA 脚本" 最后一个加载.
- 如果新的父窗口总是在顶部, 而子窗口不是, UIA 会阻止 Gui 的 +Parent 选项在现有窗口上工作.

有关详情, 请参阅 Enable interaction with administrative programs 论坛存档贴

dftg