如何在 C++ 中将一个 exe 文件作为资源嵌入到另一个 exe 文件中?

How to embed an exe file into another exe file as a resource in C++?

我正在尝试使用预构建的 .exe 文件作为我的 C++ 项目中的资源,搜索后我完成了以下步骤:

步骤 1 新建一个C++工程,在Source.cpp文件中放入如下代码

#include<iostream>
#include<Windows.h>
#include<fstream>
#define IDB_EMBEDEXE 52
using namespace std;
int main() {

    int count = 2;

    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), __TEXT("BINARY"));
    HGLOBAL hGlobal = LoadResource(NULL, hResource);
    size_t exeSiz = SizeofResource(NULL, hResource);
    void* exeBuf = LockResource(hGlobal);

    ofstream outfile((char*)exeBuf, ios::out | ios::binary);
    if (!outfile)
        exit(9);
    outfile.write((char*)exeBuf, exeSiz);
    system((char*)exeBuf);

    return 0;
}

Step2新建资源文件(.rc)
1- 项目>添加新项目
2- 从 Installed>Visual C++>Resource 选择 Resource File (.rc) 让我们将其命名为 Resource.rc

Step3编辑刚刚创建的头文件resource.h Step2,在头文件中加入如下行:
#define IDB_EMBEDEXE 52

Step4 通过右击编辑 Resource.rc 文件>打开>源代码(文本)编辑器,在第一个 #include 语句之后添加以下代码(即在 #include "resource.h"

之后
#define IDB_EMBEDEXE 52
IDB_EMBEDEXE    BINARY      "C:\Users\Almohandis\source\repos\Project7\sum2num.exe"

完全按照这些步骤执行后,我仍然在 cmd 中收到以下错误(而不是在 Visual Studio 中):

'MZ' is not recognized as an internal or external command, operable program or batch file.

程序以代码0结束

我认为调用 system() 是什么导致了问题,尤其是我传递的参数。

注意sum2num.exe文件的二进制表示以MZ....

开头

如果您的 #define 已经在 resource.h 中,则无需在您的源代码中复制它。只需在您的代码中使用 #include "resource.h"

无论如何,您应该使用 pre-defined RCDATA 资源类型,而不是创建自定义 BINARY 类型。

也就是说,您对 ofstreamsystem() 的使用都是错误的。您正在向他们传递资源的原始二进制数据,但他们期望的是文件路径。您正在使用 .rc 文件中的文件路径来指定将其二进制数据复制到资源中的文件。正如您所期望的那样,该资源不包含该文件路径。

试试这个:

resource.h

...
#define IDB_EMBEDEXE 52
...

Resource.rc

#include "resource.h"
...
IDB_EMBEDEXE    RCDATA      "C:\Users\Almohandis\source\repos\Project7\sum2num.exe"
...

Source.cpp

#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include "resource.h"
using namespace std;
        
int main() {

    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), RT_RCDATA);
    if (!hResource)
        return 1;

    HGLOBAL hGlobal = LoadResource(NULL, hResource);
    if (!hGlobal)
        return 2;

    DWORD exeSiz = SizeofResource(NULL, hResource);
    if (!exeSiz)
        return 3;

    void* exeBuf = LockResource(hGlobal);
    if (!exeBuf)
        return 4;

    char tempPath[MAX_PATH] = {};
    if (!GetTempPathA(MAX_PATH, path))
        return 5;

    string fullPath = string(tempPath) + "sum2num.exe";

    ofstream outfile(fullPath.c_str(), ios::binary);
    if (!outfile.is_open())
        return 6;

    int res = (outfile.write((char*)exeBuf, exeSiz)) ? 0 : 7;
    outfile.close();

    if (res == 0) {
        system(fullPath.c_str());
    }

    remove(fullPath.c_str());

    return res;
}