setfileattributes可一次性设置多个文件属性,通过按位或组合file_attribute_hidden、file_attribute_readonly等标志;需注意系统属性需管理员权限,unicode路径须用宽字符版本。

用 SetFileAttributes 一次性设置多个文件属性
Windows 下控制文件隐藏、只读、系统等属性,核心就是 SetFileAttributes 函数,它接受一个路径和一个整数掩码(flag)。关键在于:这些属性不是互斥的,可以按位或(|)组合使用。
常见属性常量定义在 winbase.h(通常通过 windows.h 引入):
-
FILE_ATTRIBUTE_HIDDEN—— 隐藏 -
FILE_ATTRIBUTE_READONLY—— 只读 -
FILE_ATTRIBUTE_SYSTEM—— 系统文件(需管理员权限才可设) -
FILE_ATTRIBUTE_ARCHIVE—— 归档(默认开启,一般不用动)
示例:把 "config.txt" 设为隐藏 + 只读:
#include <windows.h>
int main() {
if (!SetFileAttributes("config.txt", FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY)) {
// 失败:检查 GetLastError()
DWORD err = GetLastError();
// err == 5 表示拒绝访问(比如无写权限或被占用)
// err == 2 表示找不到文件
}
return 0;
}</windows.h>
为什么设了 FILE_ATTRIBUTE_SYSTEM 却失败?
系统属性不是普通用户能随意设置的。Windows 会拦截非管理员进程对 FILE_ATTRIBUTE_SYSTEM 的写入操作,返回错误码 ERROR_ACCESS_DENIED (5)。
必须满足两个条件之一才能成功:
- 程序以管理员权限运行(右键 → “以管理员身份运行”)
- 目标文件位于当前用户有完全控制权的路径(如
%USERPROFILE%\AppData\Local),且 UAC 没有进一步限制(但依然不推荐依赖这点)
注意:FILE_ATTRIBUTE_SYSTEM 和 FILE_ATTRIBUTE_HIDDEN 组合时,如果没提权,整个调用会失败——它不是“部分生效”,而是原子性失败。
如何查看/保留原有属性再叠加新属性?
直接调用 SetFileAttributes 会覆盖全部属性,不是“添加”。若只想加隐藏、同时保持原来的只读状态,得先读再写:
- 用
GetFileAttributes获取当前值 - 用按位或(
|)添加新属性 - 用
SetFileAttributes写回
示例:仅添加隐藏,不改动其他属性:
DWORD attrs = GetFileAttributes("data.bin");
if (attrs != INVALID_FILE_ATTRIBUTES) {
SetFileAttributes("data.bin", attrs | FILE_ATTRIBUTE_HIDDEN);
}
反向操作(比如取消隐藏)要用按位与+取反:attrs & ~FILE_ATTRIBUTE_HIDDEN。
Unicode 路径支持与宽字符注意事项
SetFileAttributes 默认是 ANSI 版本(SetFileAttributesA),遇到含中文、日文等路径会失败(返回 ERROR_PATH_NOT_FOUND 或乱码路径解析错误)。
正确做法是:确保使用宽字符版本 —— 在项目中定义 UNICODE 和 _UNICODE 宏,并调用 SetFileAttributesW(或直接用 SetFileAttributes,由宏自动映射):
- VS 项目属性 → 高级 → 字符集 → “使用 Unicode 字符集”
- 路径传
L"中文名.txt",而非"中文名.txt" - 不要混用窄/宽字符串:传
std::string.c_str()给宽版函数会崩溃或静默失败
跨平台代码慎用此 API;Linux/macOS 没有对应机制,chmod 也不等价于 Windows 属性。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










