将任何文件包含在主可执行文件中

Including any file to your main executable

本文关键字:可执行文件 任何 文件包      更新时间:2023-10-16

我正在寻找一种在我的主可执行文件中存储一个(或多个文件)的方法。假设我有一个名为 example.exe 的程序,我想做的是在该程序中包含另一个文件,让我们称之为 foo.exe,好吧,我需要执行 foo.exe 文件而无需动态启动它(使用 SystemShellExecute 等命令),更准确地说,运行目录中只有一个文件, 同时将 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来确定完整尺寸。然后,您可以用它做任何您想做的事情。 完成后不要忘记释放手柄! 模糊的样本在这里。

鉴于您的目标,我认为您的下一步是将此二进制文件复制到临时可执行文件,执行它,然后删除它。 我假设您的问题更多地是关于嵌入和加载而不是后续步骤,所以我将在这里停止。

相关文章: