File.SetAttributes 是覆盖而非追加属性,需先读取再按位或(添加)或按位与非(移除);路径须存在且有权限,隐藏属性仅影响默认显示,不提供安全保护。

用 File.SetAttributes 直接改,不是“设置”而是“覆盖”
很多人以为 File.SetAttributes 是追加或切换某个属性(比如只把隐藏加上去),其实它是一次性写入完整属性值——旧的 FileAttributes 会被完全替换。如果你只想加隐藏、保留只读/系统等其他状态,必须先读出来再按位或运算。
- 错误写法:
File.SetAttributes(path, FileAttributes.Hidden)→ 会清掉只读、存档、压缩等所有其他属性 - 正确做法:先
File.GetAttributes(path),再用|加上FileAttributes.Hidden - 如果路径不存在,会抛
FileNotFoundException;权限不足则抛UnauthorizedAccessException
隐藏文件时务必检查权限和路径有效性
Windows 下对系统目录(如 C:Windows)、受保护用户目录(如 C:UsersDefault)或 NTFS 权限受限位置,即使你是管理员也可能被拒绝写属性。而且 SetAttributes 对符号链接、重解析点、网络驱动器行为不一致。
- 必须确保路径存在且可访问,建议先用
File.Exists(path)或Directory.Exists(path)判断 - 若操作失败,检查当前进程是否以管理员权限运行(尤其涉及系统目录时)
- 对网络路径(
\servershare),部分 SMB 版本不支持隐藏属性,会静默失败或抛IOException
FileAttributes.Hidden 在不同场景下的实际效果差异
隐藏属性只是让文件在资源管理器默认视图里不显示,不等于加密或访问控制。它的生效依赖于宿主环境是否尊重该标志——比如 CMD 的 dir 默认不显示,但加 /a:h 就能列出来;.NET 的 Directory.GetFiles 默认也不返回隐藏文件,除非显式传 SearchOption.AllDirectories 和 SearchOption.TopDirectoryOnly 配合 new EnumerationOptions { AttributesToSkip = FileAttributes.Hidden }。
- 资源管理器中需开启“显示隐藏的文件、文件夹和驱动器”才可见
-
Directory.GetFiles(path)默认跳过隐藏项;要用Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)+ 自定义过滤才能包含 - 某些杀毒软件或备份工具会主动忽略
Hidden文件,这不是 .NET 的问题,是下游工具的行为
别漏掉“取消隐藏”的逻辑——清除位比设置更易出错
取消隐藏不是传 FileAttributes.Normal,那会抹掉所有其他属性。正确方式是用按位与取反:用 ~FileAttributes.Hidden 再与原属性做 & 运算。
- 错误:
File.SetAttributes(path, FileAttributes.Normal)→ 强制清空所有属性 - 正确:
var attrs = File.GetAttributes(path); File.SetAttributes(path, attrs & ~FileAttributes.Hidden); - 如果文件原本是
ReadOnly | Hidden,直接设Normal会导致只读丢失,可能引发后续写入失败
按位操作容易手抖,建议封装成小方法,比如 ToggleHidden(string path, bool hide),避免每次重复写逻辑。


















