# 长路径 [v1.1.31+]

一般来说, 程序受到两种路径长度限制的影响:

1. 操作系统提供的函数通常将路径限制为 259 个字符, 也有一些例外.
2. 处理程序内路径的代码可能依赖于第一个限制来简化代码, 从而有效地设置了另一个 259 个字符的限制.

这些限制通常被称为 "MAX_PATH 限制", 常量 `MAX_PATH`, 其值为 260. 一般为空终止符保留一个字符, 为实际路径保留 259 个字符.

AutoHotkey [v1.1.31+] (不包括 ANSI 版本) 在大多数情况下删除了第二种类型, 这使得脚本可以围绕第一种类型工作. 有两种方法可以做到这一点:

- 长路径可以在 Windows 10 上为 AutoHotkey 和所有其他长路径感知程序启用. 有关详细信息, 请参阅 Microsoft 文档. 简而言之, 这使大多数命令和函数能够透明地处理长路径, 但需要 Windows 10 1607 版本或更高版本.
- 在很多情况下, 在路径前面加上前缀 `\\?\` 使其超过通常的限制. 但是, 有一些系统函数不支持(或者通常不支持长路径). 有关详细信息, 请参阅已知限制.

## 长路径前缀

如果底层系统函数支持 `\\?\` 前缀 -- 例如, `\\?\C:\My Folder` -- 将限制增加到 32,767 个字符. 但是, 它通过跳过路径规范化来实现这一点. 路径的某些元素通常会被规范化删除或更改, 但它们会成为文件实际路径的一部分. 必须小心, 因为这允许创建 "正常" 程序无法访问的路径.

特别是, 规范化:

- 解析相对路径, 如 `dir\file.ext`, `\file.ext` 和 `C:file.ext`(注意没有反斜杠).
- 解析相关部分, 如 `\..` 和 `\.`.
- 规范化组件/目录分隔符, 用 `\` 替换 `/` 并消除多余的分隔符.
- 删除某些字符, 如组件末尾的单个句点(`dir.\file`) 或尾随空格和句点(`dir\filename . .`).

在应用前缀之前, 可以通过下面定义的函数将路径传递给 GetFullPathName, 从而显式地规范化路径. 例如:

    MsgBox % "\\?\" NormalizePath("..\file.ext")

    NormalizePath(path) {
        cc := DllCall("GetFullPathName", "str", path, "uint", 0, "ptr", 0, "ptr", 0, "uint")
        VarSetCapacity(buf, cc*2)
        DllCall("GetFullPathName", "str", path, "uint", cc, "str", buf, "ptr", 0)
        return buf
    }

带有 `\\?\` 前缀的路径也可以被这个函数规范化. 但是, 在这种情况下, 永远不会使用工作目录, 而根目录是 `\\?\`(例如, `\\?\C:\..` 解析为 `\\?\`, 而 `C:\..` 解析为 `C:\`).

## 已知限制

AutoHotkey 的 ANSI 版本不支持长路径.

尽管路径本身不再限制为 259 个字符, 但是每部分(文件或目录名) 也不能超过文件系统施加的硬限制(通常为255个字符).

由于底层系统函数的限制, 下面这些不支持长路径:

- DllCall()(用于 DllFile 和 Function)
- FileCopyDir
- FileCreateShortcut
- FileGetShortcut
- FileMoveDir, 除非使用 R 选项
- FileRecycle
- FileRemoveDir, 除非 Recurse 为 false
- SoundPlay(限制为 127 个字符)
- Drive Label 和 DriveGet(除了 Type)
- 返回特殊的文件夹路径的内置变量(长路径可能始终无法实现): A_AppData, A_Desktop, A_MyDocuments, ProgramFiles, A_ProgramFiles, A_Programs, A_StartMenu, A_Startup 和常见变量, A_Temp 和 A_WinDir

仅在 Windows 10 启用长路径感知时, SetWorkingDir 和 A_WorkingDir 才支持长路径, 因为无法使用 `\\?\` 前缀. 如果工作目录超过 MAX_PATH, 则无法使用 Run 来启动程序. 这些限制是由操作系统强加的.

似乎无法运行完整路径超过 MAX_PATH 的可执行文件. 在这种情况下, 就不可能完全测试旨在支持更长的可执行路径的任何更改. 因此, 已为以下各项保留了 MAX_PATH 限制:

- ahk_exe
- 默认脚本的路径, 该路径基于当前可执行文件的路径.
- 检索 AutoHotkey 安装目录, 该目录由 A_AhkPath 在编译脚本中使用, 可能用于启动 Window Spy 或帮助文件.
- WinGet ProcessPath.
- WinGet ProcessName(理论上这不是个问题, 因为它只应用于名称部分, 而且 NTFS 只支持最多 255 个字符的名称).

错误消息中显示的长 #Include 路径可以任意截断.

dftg