【发布时间】:2019-09-27 03:21:47
【问题描述】:
我正在 Windows 10 中构建 Haskell 命令行应用程序,并尝试通过跟踪系统调用并查看哪些失败来调试有关 Windows 260 字符文件路径限制的问题。
我为此使用了 procmon (https://docs.microsoft.com/en-us/sysinternals/downloads/procmon),这看起来相当不错,但尽管它显示了许多相关的日志条目,但我惊讶地发现它并没有显示实际的特定 CreateFileW 调用的条目超过 260 个字符并导致我的应用程序崩溃。
我曾短暂尝试过 Win32 API Monitor (https://www.apimonitor.com),但无法完全理解它;它似乎更适合附加到已经运行的 GUI 应用程序而不是需要在特定目录中启动的命令行应用程序等。
有没有比这些更好的选择,或者更好的方法?
【问题讨论】:
-
"我惊讶地发现它没有显示实际超过 260 个字符的特定 CreateFileW 调用的条目并导致我的应用程序崩溃" - 因为没有它记录。调用很可能在更高级别的 API 层被拒绝,当输入数据第一次被验证时,早在它到达文件系统层之前。 Procmon 记录较低级别的活动,而不是较高级别的 API。您正在寻找像 API Monitor 这样的工具。如果您遇到问题,请提出一个新问题。
-
Procmon 在内核级别挂钩。内核、系统组件和低级 API 库实现使用本机 NT API,它使用计数的 Unicode (UTF-16LE) 字符串,最多可以有 32767 个代码点。
MAX_PATH限制的存在是由于用户模式库如何将路径从 DOS 转换为本机 NT。它用于与遗留应用程序兼容,但也允许无条件使用相对较小的静态(每线程)翻译缓冲区,这比 90 年代初期的动态字符串更有效。 -
对于长文件路径,您的应用程序可以通过
GetFullPathNameW手动规范化并将结果转换为设备路径。后者从设备连接的调用者对象目录开始。 Windows 对此对象目录有两个前缀——“\\.\”是规范化的,而“\\?\”不是针对创建/打开进行规范化的。您想要非规范化前缀,例如“\\?\C:\Windows”。如果路径已经以“\\.\”开头,只需将其替换为“\\?\”。如果它是 UNC 但不是设备路径,例如“\\server\share”,则将其显式转换为“UNC”设备连接点——例如“\\?\UNC\server\share”。 -
@ErykSun 请注意,从 Windows 10 v1607 开始,可以避免
MAX_PATH限制,而无需诉诸\\?\或\\?\UNC\或设备路径,但 behavior has to manually opted into, see MSDN for details。 -
@RemyLebeau,即使应用程序选择加入,长 DOS 路径支持仍然需要在系统级别启用该策略,默认情况下禁用该策略,所以最终我们还没有达到即使在 Windows 10 中,应用程序也可以依赖长路径。Windows 7 和 8 也不支持它,因此需要长路径的应用程序必须通过手动规范化并在创建或打开上下文。
标签: windows debugging winapi windows-console procmon