将任何文件包含在主可执行文件中
Including any file to your main executable
我正在寻找一种在我的主可执行文件中存储一个(或多个文件)的方法。假设我有一个名为 example.exe 的程序,我想做的是在该程序中包含另一个文件,让我们称之为 foo.exe,好吧,我需要执行 foo.exe 文件而无需动态启动它(使用 System 或 ShellExecute 等命令),更准确地说,运行目录中只有一个文件, 同时将 foo.exe 文件临时复制到正在运行的目录(可能不可见)或临时目录,如 %LOCALAPPDATA%,运行它(使用 Shell 或 ShellExecute),然后在完成操作后删除该文件。提前谢谢。
示例.exe//示例.cpp
#include <windows.h>
//What I need to include?
int WINAPI WinMain(HINSTANCE Inst, HINSTANCE PrevInst,
LPSTR CmdLine, int CmdShow)
{
//What I need to do here?
return 0;
}
这是可能的,但很难。
首先,您需要编译foo
项目并获得foo.exe
。
在example
项目中,您应该创建文件 resource.h 和 resource.rc:
资源.h
#define FOO_RESOURCE 1000
资源.rc
#include "resource.h"
FOO_RESOURCE RCDATA "path to foo.exe"
其次,例如.cpp您应该加载二进制数据并存储到文件中:
#include "resource.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR sCmdLine, int nCmdShow) {
HRSRC hRSrc = ::FindResource(hInstance, MAKEINTRESOURCE(FOO_RESOURCE), RT_RCDATA);
HGLOBAL hResource = ::LoadResource(NULL, hRSrc);
unsigned char* data = (unsigned char*)::LockResource(hResource);
DWORD size = ::SizeofResource(NULL, hRSrc);
// Store size bytes of data to "foo.exe"
_TCHAR filename[MAX_PATH];
::GetEnvironmentVariable(_T("LOCALAPPDATA"), filename, MAX_PATH);
size_t filenameLength = _tcslen(filename);
if (filename[filenameLength - 1] == _T(''))
_tcscat(filename, _T("foo.exe"));
else
_tcscat(filename, _T("\foo.exe"));
HANDLE hFile = ::CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD written;
::WriteFile(hFile, data, size, &written, NULL);
::CloseHandle(hFile);
::ShellExecute(NULL, _T("open"), filename, NULL, NULL, SW_SHOWNORMAL);
// You don't need to unlock resources
}
至少,您需要通过资源编译器 (rc.exe) 编译 .rc 文件。它给出.res文件。您应该链接到示例.exe的此 .res 文件。
VS可以简化流程。只需尝试将资源添加到example
项目即可。
三种常见的解决方案(在互联网上广泛记录):
-
Windows资源(使用Visual Studio易于创建,检索数据所需的一些API调用);
-
使用像
xxd
这样的工具自动生成(可能作为预构建步骤)包含存储在数组中的 EXEP。然后从主程序使用它很简单: -
将数据及其大小追加到可执行文件(通常作为预生成步骤)。要提取它,您必须在文件的末尾(可能利用它已经在内存中映射的事实),读取大小,相应地返回,瞧,这是您的数据。
右键单击项目,选择"添加",然后选择"资源..."。 对于弹出的对话框,选择"导入...",然后选择您的文件。 这包括可执行文件中的二进制文件。
现在,在代码中,包含 "Windows.h"
,并使用 FindResource
获取数据的句柄,然后LoadResource
将文件加载到内存中并获取指向它的指针。 您还需要SizeofResource
来确定完整尺寸。然后,您可以用它做任何您想做的事情。 完成后不要忘记释放手柄! 模糊的样本在这里。
鉴于您的目标,我认为您的下一步是将此二进制文件复制到临时可执行文件,执行它,然后删除它。 我假设您的问题更多地是关于嵌入和加载而不是后续步骤,所以我将在这里停止。
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- CMake:如何将库 A 链接到库 B,然后将可执行文件链接到库 A
- 如何使字符串出现在编译的二进制可执行文件的开头?
- 程序在使用 system() 启动另一个可执行文件时停止
- 如何更改使用 CPack 安装的可执行文件的名称?
- 在Linux上使用Clang / OLLVM交叉编译helloworld Windows可执行文件时的问题
- CMake:我们可以为一组不形成可执行文件或库的特定文件指定包含目录吗?
- 如何将图像传入C++可执行文件并将输出图像存储在新目录中?
- 共享库 (.so) 没有扩展名的 Linux 可执行文件之间的区别?
- 测量任何 Windows 可执行文件的内存使用情况和执行时间
- 使用 CodeBlocks + GCC 构建的可执行文件是否可以在任何 Windows 上运行?
- 如果给定正确的运行时库,x86 可执行文件是否可以在任何 x86 平台上运行
- 在运行时动态更新二进制文件(可执行文件)而不停止的任何类型的方法
- 如何将任何 *.jpg图像嵌入Win32可执行文件中并在运行时使用它
- 创建不需要任何进一步安装即可在其他计算机上工作的可执行文件?
- 将任何文件包含在主可执行文件中
- 可执行文件在无限大小写(任何时间限制)下将运行多长时间
- 除了 clang 之外,"clang -S -emit-llvm file.cpp"运行任何其他可执行文件吗?
- 用宏生成文件,不生成任何可执行文件