跳转至

Windows 保留设备名(nul / con / aux)文件无法删除

一句话总结:nul、con、aux 这类文件名被 Windows 当作设备名而非普通文件,资源管理器与常规 del 命令在 Win32 路径解析层就被拦截,所以表现为「文件明明存在却删不掉」;解法是绕过路径解析——加 \\?\ 扩展前缀,或换用 Git Bash / WSL 直接走底层文件系统。

来源:DeepSeek 对话《文件无法删除》 https://chat.deepseek.com/share/nv1d8fd46lceyiv0jn


1. 为什么删不掉

Windows 继承自 MS-DOS,把一批名字保留给硬件设备,任何同名的普通文件都会被系统当作设备来处理:

保留名 原本含义
NUL 空设备(写入即丢弃、读取即 EOF)
CON 控制台
PRN 打印机
AUX 辅助设备(通常是串口)
COM1 ~ COM9 串口
LPT1 ~ LPT9 并口

Win32 子系统在解析路径时先做保留名匹配,一旦命中就直接转发给设备驱动,根本不会走到文件系统。所以资源管理器觉得「该路径不存在」,删除操作自然失败;com1.txt 这类「设备名 + 扩展名」的形式同样会被拦截。

这些是行业共识的客观事实,与是否管理员权限无关——提权也删不掉。


2. 核心思路:\\?\ 扩展路径前缀

\\?\ 是 Win32 的 UNC 扩展路径格式,启用后会关闭路径规范化(不再解析 ..、/、保留设备名),路径被原样交给内核对象管理器,直接落到 NTFS 上。

  • 只支持绝对路径,且必须用反斜杠:\\?\C:\dir\nul 有效,\\?\C:/dir/nul 无效
  • 注意转义:CMD / PowerShell 里是两个反斜杠 \\?\,在 JSON、正则或部分脚本语言中需要写成四个 \\\\?\\

3. 可选的删除方案

方案 核心命令 优势 前提
.NET API [System.IO.File]::Delete('\\?\C:\完整路径\nul') 最直接,一次调用 有 PowerShell
PowerShell Remove-Item -LiteralPath "\\?\C:\完整路径\nul" -Force 无需记 .NET 语法 有 PowerShell
CMD del "\\?\C:\完整路径\nul" 最短 命令提示符
Git Bash 在文件所在目录右键 → Git Bash Here → rm nul 最简单,容错高 已装 Git for Windows
WSL rm /mnt/c/完整路径/nul 走 Linux 内核,彻底规避 Win32 限制 已装 WSL
7-Zip 用 7-Zip 打开父目录,选中后 Shift + Delete 图形界面,兜底手段 资源管理器已失效时

4. 操作步骤

4.1 先拿到绝对路径

在资源管理器中选中该文件,按住 Shift 右键 → 「复制为路径」,得到带引号的完整路径。后续命令把引号去掉、在前面补上 \\?\ 即可。

4.2 PowerShell

Remove-Item -LiteralPath "\\?\C:\Users\YOUR_USER\Desktop\nul" -Force

或直接用 .NET:

[System.IO.File]::Delete('\\?\C:\Users\YOUR_USER\Desktop\nul')

-LiteralPath 不能省:-Path 仍会做通配符与路径解析,可能再次踩到保留名。

4.3 CMD

del "\\?\C:\Users\YOUR_USER\Desktop\nul"

4.4 Git Bash(推荐图省事时用)

  1. 打开文件所在的文件夹
  2. 在空白处右键 → Git Bash Here
  3. 执行:
rm nul

Git Bash 自带 MSYS2 运行时,会用 POSIX 路径语义直接调用底层接口,nul 就是普通文件名,没有特殊性。

4.5 WSL

rm /mnt/c/Users/YOUR_USER/Desktop/nul

4.6 7-Zip

用 7-Zip 的文件管理器打开父目录,找到 nul 后按 Shift + Delete。7-Zip 不走资源管理器的路径校验,部分场景可以直接删掉;删不掉时还能先重命名再删。


5. 排查顺序建议

  1. Git Bash 里 rm nul —— 一步到位,几乎必成
  2. 没装 Git → PowerShell 的 \\\\?\\ 方案
  3. 还失败 → 7-Zip 重命名后再删
  4. 仍然报错时,记下具体错误码(如 Access denied / The system cannot find the file specified),再判断是权限、文件系统损坏还是被进程占用

6. 预防

  • 从 Linux / WSL / 压缩包解压、跨平台同步时最容易带出这类文件,解压到 NTFS 前先看文件名
  • 建目录时避免 con、prn、aux、nul、com1~com9、lpt1~lpt9,含扩展名也算
  • 写脚本批量生成文件名时,把保留名列表做成黑名单过滤