最近忽然想起来一个问题:如何给一个做好的 EXE 加入其他的内容?比如,我编写一个 EXE 需要更改内容而又不想重新 Build 代码。
经过研究,可以通过给EXE 添加 Resource 的方法来实现这一目标。在 https://github.com/tc-hib/go-winres 这里有一个从命令行给 EXE 添加Resource 的项目。配合这个项目可以实现前述目标。
首先,编写一个测试代码,使用 VC 编写在 VS2019 下编译通过:
#include <windows.h>
#include <iostream>
// 回调函数用于枚举资源
BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam) {
// 每找到一个资源,就增加计数
(*(int*)lParam)++;
return TRUE; // 继续枚举
}
int main()
{
HMODULE hModule = GetModuleHandle(NULL); // 获取当前模块句柄
int resourceCount = 0; // 用于计数的变量
// 枚举所有RT_RCDATA类型的资源
EnumResourceNames(hModule, RT_RCDATA, EnumResNameProc, (LONG_PTR)&resourceCount);
std::cout << "Number of RT_RCDATA resources: " << resourceCount << std::endl;
return 0;
}
代码非常简单,单纯的输出当前EXE RT_RCDATA类型的 Resource 数量。
接下来将go-winres.exe放在同一个目录下,然后运行下面的命令
go-winres.exe init
对应的会生成 winres 目录,其中有下面三个文件
前面2个是可以作为EXE 的图标的,winres.json是配置文件。例如,我们对这个目录放置一个 png 文件,然后修改如下,增加 RT_RCDATA的部分:
"RT_GROUP_ICON": {
"APP": {
"0000": [
"icon.png",
"icon16.png"
]
}
},
"RT_RCDATA": {
"OTHER": {
"0000": "2.png"
}
},
"RT_MANIFEST": {
"#1": {
"0409": {
"identity": {
"name": "",
"version": ""
运行如下命令:
go-winres.exe patch ResourceTest.exe
工具会自动给 ResourceTest.exe 添加内容,之后再次运行:
如果使用 CFF 工具还可以看到多了一个 Resource。这样,你可以在代码中先判断Resource数量,然后再进行动作。
官方提供的版本(和 Github上的相同,0.3.3版本)