在windows下创建隐藏文件必须在createfile的dwflagsandattributes参数中显式指定file_attribute_hidden,并配合create_always或create_new使用;std::filesystem不支持创建时设隐藏属性,需调用winapi setfileattributes;隐藏仅为shell显示标记,不影响访问权限与底层api行为。

Windows 下用 CreateFile 创建隐藏文件要设对 dwFlagsAndAttributes
直接调用 CreateFile 不会自动隐藏文件,必须显式传入 FILE_ATTRIBUTE_HIDDEN 标志。这个标志得和 CREATE_ALWAYS 或 CREATE_NEW 一起用,不能只靠后续调用 SetFileAttributes —— 那样多一次系统调用,且在并发场景下有竞态风险(文件刚创建、还没来得及设属性就被其他进程看到)。
常见错误是把 FILE_ATTRIBUTE_HIDDEN 错当成打开模式传给 dwDesiredAccess,或者漏掉 FILE_ATTRIBUTE_NORMAL 的屏蔽逻辑(比如误写成 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL,后者会覆盖前者)。
-
dwFlagsAndAttributes参数必须包含FILE_ATTRIBUTE_HIDDEN,其他属性如FILE_ATTRIBUTE_ARCHIVE可按需叠加 - 不要在
CreateFile后立刻用SetFileAttributes补设——除非你明确需要延迟隐藏或处理已存在文件 - 如果文件已存在,
CreateFile默认不会修改其属性;此时需先用GetFileAttributes读取原属性,再用SetFileAttributes合并FILE_ATTRIBUTE_HIDDEN
std::filesystem::create_directories 不能设隐藏,得手动补 std::filesystem::permissions
C++17 的 std::filesystem 没提供创建时设隐藏属性的接口。它建目录或文件后,属性始终是默认值(FILE_ATTRIBUTE_NORMAL)。想隐藏,必须额外调用 std::filesystem::permissions 并传入 std::filesystem::perms::owner_read | std::filesystem::perms::owner_write 等等?不对——Windows 上这函数映射的是 ACL 权限,不是文件属性。
真正有效的是用 std::filesystem::status 获取 file_status,再转成 Windows 原生句柄,最后调用 SetFileAttributes。但更简单直接的做法是:绕过 std::filesystem 的“跨平台抽象”,在 Windows 上就用 WinAPI。
- 别指望
std::filesystem::create_directories("foo")能产生隐藏目录——它不会 -
std::filesystem::permissions在 Windows 上改的是 NTFS 权限位,不影响“隐藏”这个 Explorer 层面的属性 - 若坚持用
std::filesystem创建,后续必须调用SetFileAttributes(L"foo", FILE_ATTRIBUTE_HIDDEN),且注意路径要用宽字符(L"...")
隐藏文件在命令行和资源管理器里表现不一致,容易误判是否生效
资源管理器默认不显示隐藏文件,但 cmd 和 powershell 默认能列出(dir /a:h 是专门查隐藏项,但 dir 本身也包含隐藏文件,除非加 /a:-h)。这意味着:你以为文件“藏好了”,其实随便一个 dir 就能看见。
更麻烦的是,某些 IDE(如 VS Code)或构建工具(如 CMake)默认忽略隐藏文件,但另一些(如 Ninja)可能不忽略——行为取决于它们内部用的文件遍历逻辑是否检查 FILE_ATTRIBUTE_HIDDEN。
- 验证是否真隐藏:在资源管理器中打开“查看 → 隐藏的项目”,看文件是否灰显;同时在 CMD 执行
attrib filename,确认输出含H标记 - 不要依赖“看不见”就认为安全——隐藏 ≠ 权限控制,敏感内容该加密还得加密
- Git 默认忽略隐藏文件(
.gitignore里没特别写的话),但git add -f仍可强制加入
用 SetFileAttributes 改已有文件隐藏属性时,注意返回值和错误码
很多人调完 SetFileAttributes(L"config.ini", FILE_ATTRIBUTE_HIDDEN) 就以为完事了,结果发现没生效。最常见原因是路径不存在、权限不足,或传了非法组合(比如同时设 FILE_ATTRIBUTE_HIDDEN 和 FILE_ATTRIBUTE_SYSTEM,虽不报错但部分旧工具会拒绝处理)。
必须检查返回值:FALSE 表示失败,接着调 GetLastError() 看具体原因。常见错误码有 ERROR_FILE_NOT_FOUND(路径错)、ERROR_ACCESS_DENIED(比如文件正被其他进程以独占方式打开)。
- 路径必须是绝对路径或当前工作目录下的相对路径;相对路径在多线程环境下容易出错,建议统一用绝对路径
- 如果目标是目录,
FILE_ATTRIBUTE_HIDDEN只影响该目录本身,不递归作用于子项 - 调用前确保文件/目录未被其他程序以
FILE_SHARE_NONE方式打开,否则SetFileAttributes会失败
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











