将.exe文件嵌入C++程序中?

3
我编写了一个C++程序,并想在其中执行我的第二个程序,该程序为exe文件。问题是我想将我的程序共享给他人作为一个单一的文件。
当我在互联网上搜索时,我找到了这个解决方案。
只需使用 .rc 文件在编译时将第二个 .exe 文件作为二进制资源存储在主 .exe 中。在运行时,您可以使用 FindResource()、LoadResource() 和 LockResource() 来访问它,然后将其写入临时文件并传递给 system()。
但我不知道如何“将 .exe 文件存储为二进制资源”。
我目前正在使用 CreateProcess() 启动我的第二个程序,而且它工作得非常好。有人能为我编写一些示例吗?

存储它不应与存储任何其他二进制资源有所不同。但是,您可能需要将文件提取到硬盘上的某个位置才能使用它。 - drescherjm
1
你在使用Visual Studio吗?你的项目中有一个资源脚本(.rc文件)吗?你知道如何使用资源编辑器吗?如果我们要提供正确的解决方案,我们需要更多信息。 - Adrian Mole
@drescherjm 你好,感谢你的帮助。所以我只需要将.exe重命名为.rc吗? - Jason Lam
你的项目中是否有任何一个扩展名为.rc.rc2的文件?(我也不使用Cygwin,但如果有资源脚本,它可以被编辑以包含二进制资源。) - Adrian Mole
@AdrianMole 我使用一个 .rc 文件为我的程序添加图标。我需要先将 .rc 文件编译成 .res 文件,然后再将 .res 与我的主程序一起编译。 - Jason Lam
显示剩余4条评论
1个回答

6
在项目的资源脚本中(定义图标、对话框等的.rc文件),您可以通过添加以下行来添加二进制资源:
IDB_EMBEDEXE    BINARY      "<path>\\EmbedProgram.exe"

IDB_EMBEDEXE的令牌/宏应该在一个头文件中定义,该头文件被包含在使用它的资源脚本和C++源代码中; 这将是传递给FindResource()调用的lpName参数,您可以使用MAKEINTRESOURCE(IDB_EMBEDEXE)来形成它。 对于lpType参数,请指定"BINARY"(对于Unicode构建,请使用L"BINARY")。

像这样:

#define IDB_EMBEDEXE 13232 // Or whatever suitable value you need
//...
// In the C++ code:
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), _TEXT("BINARY"));
HGLOBAL hGlobal = LoadResource(NULL, hResource);
size_t exeSiz = SizeofResource(NULL, hResource); // Size of the embedded data
void*  exeBuf = LockResource(hGlobal);           // usable pointer to that data

// You can now write the buffer to disk using "exeBuf" and "exeSiz"

指定的可执行文件将被完全嵌入(作为二进制)资源到您构建的可执行文件中,并可以像引用文章中描述的那样提取,写入磁盘并执行。

通过将 RT_RCDATA 更改为 "BINARY"FindResource() 返回一个句柄,因此它可以正常工作。 - Jason Lam
不,我错了,当我说我错了时!RT_RCDATA已经定义为MAKINTRESOURCE(10)。我想我需要一些烈酒。坚持使用“BINARY”名称吧!! - Adrian Mole
好的,一切都像魔法般地运行正常。还有一个问题,在我通过CreateProcess()运行exe之后,如何终止它? - Jason Lam
1
你好,非常感谢你的帮助。在我的Windows 10电脑上运行得非常顺畅。最近,我尝试在一台Windows 7电脑上运行同样的程序,但是当执行WriteFile(hFile, exeBuf, exeSiz, NULL, NULL);时程序崩溃了。这是怎么回事呢?在Windows 10上我没有遇到任何问题。谢谢。 - Jason Lam
1
我通过将NULL更改为&at来解决了这个问题。参考链接。顺便说一句,谢谢。 - Jason Lam
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接