给 EXE 加入 Resource

最近忽然想起来一个问题:如何给一个做好的 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版本)