暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

"文件名或扩展名太长"导致的文件删除失败

青衣十三楼飞花堂 2020-06-19
1890

标题: "文件名或扩展名太长"导致的文件删除失败

☆ 问题描述
☆ 问题复现
☆ 问题起因
☆ 问题解决
    1) subst
    2) \\?\前缀(有条件成功)
        2.1Win10 1709的困惑
        2.2) 尾部有空格的文件名
    3) powershell(失败)
    4) 第三方工具或自编程(未测试)

☆ 问题描述

某人说Win8有两个文件夹无法删除,起初以为是NTFS损坏所致,结果是目录树中某些文件名超长所致。按她的说法,其学生通过微信发过来论文资料压缩包,她解压后形成的目录树。我在cmd中尝试del、rename,均失败。

稍微研究了一下这个问题,发现Win7、Win8相对棘手,Win10有所改进。本文不考虑用LiveCD启动Linux的解决方案。

☆ 问题复现

在Win7上复现问题。

mkdir c:\long_path_test\evil
cd c:\long_path_test\evil
echo "scz is here" > evil.txt
rename evil.txt 0000000000000000...eeeeeeeeeeeeeeee.txt

长文件名非扩展名部分由如下行构成:

0000000000000000
1111111111111111
2222222222222222
3333333333333333
4444444444444444
5555555555555555
6666666666666666
7777777777777777
8888888888888888
9999999999999999
aaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbb
cccccccccccccccc
dddddddddddddddd
eeeeeeeeeeeeeeee

rename失败,报错:

系统无法接受请求的路径或文件名。            // 中文Win7
The system cannot find the path specified.  // 英文Win10 1709

用subst弄个虚拟盘符"T:",切换到T盘,再次rename。

subst t: %cd%
t:
rename evil.txt 00...ee.txt
type 00...ee.txt

rename成功,type可以正常显示文件内容。切回C盘根目录,删除虚拟盘符:

c:
subst t: /d
cd \

在资源管理器中双击"00…ee.txt",提示:

文件名或扩展名太长。

试图删除"c:\long_path_test"时报错:

文件名对目标文件夹可能过长。您可以缩短文件名并重试,或者尝试路径较短的位置。

在资源管理器中试图直接删除"00…ee.txt",报同样的错;其右键菜单没有"删除"、"重命名"等。选中"00…ee.txt",按F2试图改名,没反应。此时先打开notepad,再通过"文件->打开"去查看"c:\long_path_test\evil\"目录,文件对话框中干脆不显示"00…ee.txt",就跟空目录一样。

假设通过前述办法制造了删不掉的"00…ee.txt",用7-Zip打包long_path_test目录成long_path_test.7z。去别处解压long_path_test.7z,立即复现问题。

http://scz.617.cn/windows/long_path_test.7z

☆ 问题起因

Windows有个著名常量MAX_PATH,等于260。很多文件操作会检查路径长度是否超过该值,该检查与文件系统是否支持超长文件名无关,与使用FAT32或NTFS无关。NTFS本身支持长达32767宽字符的路径名。

参看:

Long Filenames on Windows - John Rennie [2009-05-17]
http://www.ratsauce.co.uk/notablog/longfilenames.asp

CreateFileA function
https:
//docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea

Naming Files, Paths, and Namespaces
https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
(这篇概括得不错,推荐无基础入门者阅读)

不需要逆向工程或查看泄露的NT4、2K、XP源码,微软文档中提及的这批Win32 API就是曾经有过MAX_PATH限制的API:

CreateDirectoryW
CreateDirectoryExW
GetCurrentDirectoryW
RemoveDirectoryW
SetCurrentDirectoryW

CopyFileW
CopyFile2
CopyFileExW
CreateFileW
CreateFile2
CreateHardLinkW
CreateSymbolicLinkW
DeleteFileW
FindFirstFileW
FindFirstFileExW
FindNextFileW
GetFileAttributesW
GetFileAttributesExW
SetFileAttributesW
GetFullPathNameW
GetLongPathNameW
MoveFileW
MoveFileExW
MoveFileWithProgressW
ReplaceFileW
SearchPathW
FindFirstFileNameW
FindNextFileNameW
FindFirstStreamW
FindNextStreamW
GetCompressedFileSizeW
GetFinalPathNameByHandleW

☆ 问题解决

1) subst

cd c:\long_path_test\evil
subst t: %cd%
t:
del /f /s /q *.*
c:
subst t: /d

2) \\?\前缀(有条件成功)

del C:\long_path_test\evil\00…ee.txt

报错:

文件名或扩展名太长。                        // 中文Win7
The system cannot find the path specified.  // 英文Win10 1709

del \\?\C:\long_path_test\evil\00…ee.txt

Win7、Win8仍然失败,Win10 1709成功删除。

2.1) Win10 1709的困惑

按微软官方文档说法,Win10 1607在此问题上开始有所改进,但要求如下注册表项就位:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001

我的Win10 1709该值为0,但在资源管理器中已能直接删除"00…ee.txt",与官方文档所述有出入。

若LongPathsEnabled为1,Win10中如下命令成功:

del C:\long_path_test\evil\00…ee.txt

不再需要\\?\前缀。

2.2) 尾部有空格的文件名

这事与本文主旨无关,仅为备忘。John Rennie指出\\?\前缀的一种邪恶用法:

echo "scz is here" > "\\?\C:\long_path_test\evil\tailspace.txt "

这将生成尾部有空格的文件名。

Win7、Win8、Win10在资源管理器中无法打开、删除、重命名"tailspace.txt "。如果目录树中包含这种畸形文件,整个目录树都无法删干净。如果想恶搞别人,可以试试。

可以在cmd中用\?\前缀删除这种畸形文件:

del "\\?\C:\long_path_test\evil\tailspace.txt "

3) powershell(失败)

powershell -c "Move-Item -Path 00...ee.txt -Destination evil.txt"
powershell -c "Rename-Item -Path 00...ee.txt -NewName evil.txt"
powershell -c "Remove-Item 00...ee.txt -Recurse -Force"

Win7、Win10均报错。

powershell方案可能是某些人YY出来的,所受限制同cmd中的del、rename等。或许有增强版的powershell?

4) 第三方工具或自编程(未测试)

包括但不限于:

Total Commander
Long Path Tool

当时某人Win8中没有TC,我下了个LPT,结果还要付费注册激活全功能啥的,未进一步测试。说不定360的那堆工具也能干这事。

一般你突然遭遇这种事的时候,不可能有机会自编程,你只想着用系统自带工具赶紧解决问题,然后走人。

本文TXT原文:

http://scz.617.cn/windows/202006182000.txt

Markdown排版可能导致某些特殊字符丢失。


文章转载自青衣十三楼飞花堂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论