通常的方法是调用它,将大小设置为零,保证失败并提供分配足够缓冲区所需的大小。分配一个缓冲区(不要忘记空终止的空间)并再次调用它。
在很多情况下MAX_PATH 就足够了,因为许多文件系统限制了路径名的总长度。但是,可以构造超过MAX_PATH 的合法且有用的文件名,因此查询所需的缓冲区可能是个好建议。
不要忘记最终从提供它的分配器返回缓冲区。
编辑:弗朗西斯在评论中指出,通常的配方不适用于GetModuleFileName()。不幸的是,弗朗西斯在这一点上是绝对正确的,我唯一的借口是在提供“通常”的解决方案之前我没有去查证。
我不知道那个 API 的作者在想什么,除了它可能在引入时,MAX_PATH 确实是最大可能的路径,使得正确的配方变得容易。只需在长度不少于MAX_PATH 个字符的缓冲区中进行所有文件名操作。
哦,是的,不要忘记自 1995 年左右以来的路径名称允许使用 Unicode 字符。因为 Unicode 占用更多空间,所以任何路径名前面都可以有 \\?\ 以明确请求删除该名称的字节长度限制 MAX_PATH。这使问题变得复杂。
MSDN 在标题为 File Names, Paths, and Namespaces 的文章中对路径长度有这样的说法:
最大路径长度
在 Windows API 中(带有一些
以下讨论的例外情况
段落),最大长度为
路径为MAX_PATH,定义为
260 个字符。本地路径是
结构如下:
驱动器号、冒号、反斜杠、
由反斜杠分隔的组件,
和一个终止的空字符。为了
例如,驱动器 D 上的最大路径
是“D:\<some 256 character path
string><NUL>”,其中“<NUL>”代表
不可见的终止空
当前系统的字符
代码页。 (使用字符<>
这里是为了视觉清晰,不能
有效路径字符串的一部分。)
注意文件 I/O 函数
Windows API 将“/”转换为“\”作为一部分
将名称转换为 NT 样式
名称,除非使用“\\?\”
前缀如下详述
部分。
Windows API 有很多功能
也有 Unicode 版本
允许一个扩展长度的路径
最大总路径长度为 32,767
人物。这种类型的路径是
由分开的组件组成
反斜杠,每个最大的值
在返回
lpMaximumComponentLength参数
GetVolumeInformation 函数。到
指定一个扩展长度的路径,使用
“\\?\”前缀。例如,
“\\?\D:\<very long path>”。 (这
字符 < > 在这里用于
视觉清晰度,不能成为
有效的路径字符串。)
注意最大路径32767
字符是近似的,因为
“\\?\”前缀可以扩展为
系统在运行时更长的字符串
时间,这种扩展适用于
总长度。
也可以使用“\\?\”前缀
根据构建的路径
通用命名约定 (UNC)。
要使用 UNC 指定这样的路径,请使用
“\\?\UNC\”前缀。例如,
“\\?\UNC\server\share”,其中“服务器”
是机器的名称和“共享”
是共享文件夹的名称。
这些前缀不用作
路径本身。他们表明
路径应该传递给
系统修改最少,
这意味着你不能使用
正斜杠表示路径
分隔符,或表示的句点
当前目录。还有,你
不能将“\\?\”前缀与
相对路径,因此是相对的
路径仅限于MAX_PATH
如前所述的字符
不使用“\\?\”前缀的路径。
当使用 API 创建一个
目录,指定路径不能
太长以至于你不能附加一个
8.3 文件名(即目录名不能超过MAX_PATH减12)。
shell 和文件系统有
不同的要求。有可能的
使用 Windows API 创建路径
shell 用户界面可能
处理不了。
所以一个简单的答案是分配一个大小为MAX_PATH 的缓冲区,检索名称并检查错误。如果合适,你就完成了。否则,如果它以“\\?\”开头,则获得大小为 64KB 左右的缓冲区(上面的短语“32,767 个字符的最大路径是近似的”在这里有点麻烦,所以我留下一些细节以供进一步研究)和再试一次。
溢出MAX_PATH 但不以“\\?\”开头似乎是“不可能发生”的情况。同样,接下来要做什么是您必须处理的细节。
对于以“\\Server\Share\”开头的网络名称的路径长度限制也可能有些混淆,更不用说内核对象名称空间中以“\\.\”开头的名称了。上面的文章没有说,我不确定这个API是否可以返回这样的路径。