【问题标题】:Do Windows Shell APIs work with long Unicode paths?Windows Shell API 是否适用于长 Unicode 路径?
【发布时间】:2014-06-01 01:56:47
【问题描述】:

我似乎无法在 MSDN 中找到答案。我很好奇,如果我有这样的东西:

LPITEMIDLIST pidl = NULL;
HRESULT hr = SHParseDisplayName(L"\\\\?\\C:\\Users\\Name\\Folder", NULL, &pidl, 0, NULL);

失败,HRESULT 设置为 E_INVALIDARG。如果我将路径提供为 "C:\\Users\\Name\\Folder"(仅限于 MAX_PATH 字符),问题就会消失。

这些 Shell API 是否与长 Unicode 路径不兼容?

【问题讨论】:

标签: c++ winapi windows-shell


【解决方案1】:

通常不支持,不支持。 \\?\ 是较低级别的文件 I/O API 的功能,而不是较高级别的 Shell API。 \\?\ 不代表 Shell 命名空间。

更新:对于将长文件路径解析为 PIDL 之类的事情,您可能需要手动将路径字符串分成单独的部分,并直接使用 IShellFolder 将每个部分解析为 parent/根据需要递归子 PIDL。如果没有别的,这将帮助您确定哪个子文件夹破坏了解析,然后您可以向用户报告:“抱歉,已达到 Windows 路径长度限制,无法使用路径 XXX 下的文件/文件夹”。

【讨论】:

  • 谢谢。我也那么认为。那么你如何处理超过 260 个字符的路径呢?
【解决方案2】:

不,Shell API 函数(通常)与长 Unicode 路径不兼容。

例如在SHParseDisplayName的反函数的文档中,即SHGetPathFromIDList,你发现

pszPath [out]
类型:LPTSTR
接收文件系统路径的缓冲区地址。此缓冲区的大小必须至少为 MAX_PATH 个字符。

一般来说,文档记录了每个相关函数的路径长度限制,但 AFAICS 并没有将其作为更高级别的总体一般性声明。


从开发的角度来看,创建 >MAX_PATH 路径是合理的,或者例如涉及保留名称(例如 CON)的路径,如果普通最终用户无法处理它们,因为 Windows 资源管理器拒绝处理它们。

(我刚刚检查过。Windows 8.1 Explorer 会默默地拒绝删除名为con 的文件夹。我认为应该这样做,因为普通的最终用户会发现很难删除它。)

高级用户可以绕过 shell 的路径长度限制,例如删除或重命名,通过利用命令解释器中的一些错误,通过使用subst 驱动器,通过使用 DOS 短名称,通过编写调用 API 函数的程序,以及可能的其他技术(希望不是通过磁盘编辑)。但是对于普通的最终用户来说,这样的技术是未知的。因此,当普通最终用户得到一些不想要的 >MAX_PATH 路径时,该用户就会被它所困。

【讨论】:

  • 哦,不。实际上恰恰相反。我们收到了其中一位“普通最终用户”的技术支持请求,其中包含任何开发人员“最喜欢的”行——“你的程序不起作用”。所以我花了几天的时间来深入研究原因——最终用户有一个非常长的文件夹名称,这使得路径超过 259 个字符。这就是我问的原因。不只是SHParseDisplayName,我们吃得最多的API是PathFileExists,应该禁止存在!
  • 从长远来看,提供关于“超过 Windows 的路径长度”的合理反馈(将责任归咎于应归咎于的地方)可能比尝试解决问题更好,因为如果用户得到解决方法,那么接下来用户可能会抱怨资源管理器无法处理的文件夹和文件...
  • 是的,这是处理它的一种方法。至于你的其他评论。你知道我刚刚在我的 Windows 8.1 pro 上做了一个测试。我创建了一个超过 259 个字符的文件夹(使用 \\?\ 前缀),然后在其中创建了一个文本文件。然后我删除了它并试图从回收站中恢复它并崩溃了 Windows 资源管理器......哈哈。我不敢相信我们还在 Windows 8.1 中处理这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
相关资源
最近更新 更多