在 Windows 系统中,二进制文件(或其他文件)的 “详细信息” 选项卡中的属性(如作者、版本、版权等)属于文件的 元数据(Metadata),需要通过 资源文件(.rc) 或 Win32 API 操作文件的版本信息块(Version Information Resource)。以下是具体方法:
1. 通过 .rc
资源文件定义属性
(1) 创建资源脚本文件(.rc
)
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0 // 文件版本号
PRODUCTVERSION 1,0,0,0 // 产品版本号
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 // 通常为 0 (正式版)
FILEOS VOS_NT_WINDOWS32 // 目标操作系统
FILETYPE VFT_APP // 文件类型 (应用程序)
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // LangID: 英语(美国), UTF-16
BEGIN
VALUE "CompanyName", "ZeroSound Inc.\0"
VALUE "FileDescription", "Sample Binary\0"
VALUE "FileVersion", "1.0.0.0\0"
VALUE "ProductName", "ZeroSound Product\0"
VALUE "LegalCopyright", "© 2023 ZeroSound\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // English (US), Unicode
END
END
**(2) 编译时链接资源文件
- Visual Studio:将
.rc
文件添加到项目,编译时会自动生成.res
并嵌入到二进制文件中。 - 命令行:
rc.exe my_resource.rc # 生成 .res
link.exe my_obj.obj my_res.res # 链接到可执行文件
**2. **通过 Win32 API 动态修改/读取属性
使用以下 API 操作版本信息:
**(1) 获取版本信息块大小
DWORD dwSize = GetFileVersionInfoSize("example.exe", NULL);
if (dwSize == 0) {
DWORD err = GetLastError();
}
**(2) 读取版本信息
std::vector<BYTE> buffer(dwSize);
if (!GetFileVersionInfo("example.exe", NULL, dwSize, &buffer[0])) {
// Handle error...
}
// Query specific metadata (e.g., FileDescription)
VS_FIXEDFILEINFO* pFileInfo;
UINT len;
VerQueryValue(&buffer[0], _T("\\"), (LPVOID*)&pFileInfo, &len);
// Query string values (e.g., CompanyName)
LPVOID lpValue;
VerQueryValue(&buffer[0], _T("\\StringFileInfo\\040904b0\\CompanyName"), &lpValue, &len);
_tprintf(_T("Company: %s\n"), (LPCTSTR)lpValue);
**(3) 动态修改属性
需替换文件的版本信息资源块,通常需要以下步骤:
BeginUpdateResource
UpdateResource
EndUpdateResource
示例代码较复杂,通常建议直接修改 .rc
后重新编译。
3. *关键注意事项*
- 权限要求:修改已存在的二进制文件需要管理员权限。
- 签名影响:修改元数据会破坏数字签名,需重新签名。
- Unicode支持:始终使用宽字符 API (
GetFileVersionInfoW
)。 - 常见错误码:
ERROR_RESOURCE_DATA_NOT_FOUND
:无版本信息资源。
如果需要完整的动态修改示例代码或更详细的字段说明,可以进一步探讨!
内容由零声教学AI助手提供,问题来源于学员提问