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

时间:2015-01-15 01:19:31

标签: c++

我正在搜索在主可执行文件中存储文件(或多个文件)的方法。假设我有一个名为 example.exe 的程序,我想要做的是在该程序中包含另一个文件,我们称之为 foo。 exe ,我需要执行 foo.exe 文件,而无需动态启动它(使用 System ShellExecute ),为了更准确,只在运行目录中有一个文件,还要提供 foo.exe 文件临时复制到正在运行的目录(可能是不可见的)或临时目录,如%LOCALAPPDATA%,运行它(使用 Shell ShellExecute ),然后在完成操作后,删除文件。提前谢谢。

example.exe // example.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;
}

3 个答案:

答案 0 :(得分:2)

这是可能的,但这很困难。

首先,您需要编译foo项目并获取foo.exe

example项目中,您应该创建文件 resource.h resource.rc

<强> RESOURCE.H

#define FOO_RESOURCE 1000

<强> RESOURCE.RC

#include "resource.h"
FOO_RESOURCE RCDATA "path to foo.exe"

其次,在 example.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文件。 这个.res文件应链接到 example.exe

VS可以简化流程。只是尝试将资源添加到example项目。

答案 1 :(得分:1)

三种常见解决方案(在互联网上广泛记录):

  • Windows资源(使用Visual Studio轻松创建,检索数据所需的一些API调用);

  • 使用像xxd这样的工具自动生成(可能作为预构建步骤)包含存储在数组中的exe的cpp。从主程序中使用它然后是微不足道的:

  • 将您的数据附加到可执行文件(通常作为预构建步骤)及其大小。要提取它,你必须在文件的末尾(可能利用它已经映射到内存中的事实),读取大小,相应地返回并voilà这是你的数据。

答案 2 :(得分:0)

右键单击项目,选择“添加”,然后选择“资源...”。对于弹出的对话框,选择“导入...”,然后选择您的文件。这包括您的可执行文件中的二进制文件。

现在,在您的代码中,您包含"Windows.h",并使用FindResource来获取数据句柄,然后LoadResource将文件加载到内存中并获取指向它。您还需要SizeofResource来确定完整尺寸。然后,您可以随心所欲地做任何事情。完成后别忘了释放手柄!模糊的样本是here

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