【问题标题】:How to embed an MSI in my bootstrapper exe如何在我的引导程序 exe 中嵌入 MSI
【发布时间】:2016-05-01 15:55:27
【问题描述】:

我为我的应用程序编写了一个 C++ 安装程序引导程序(硬要求,因为我需要完全控制文件的格式)。现在我试图弄清楚如何以最少的开销将我的 MSI 嵌入到我的引导 EXE 中。我所有的搜索都向我展示了相反的情况(如何在 MSI 中嵌入 EXE)。

这个安装程序必须离线工作,所以我不能让我的引导程序简单地下载文件。

我当然可以将它作为字节流嵌入到我的源文件中,但这会导致文件大小的大量开销。

【问题讨论】:

    标签: c++ windows-installer installation


    【解决方案1】:

    在二进制文件中嵌入数据作为资源并提取它是相当普遍的。这种事:

    http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

    http://www.codeproject.com/Articles/4221/Adding-and-extracting-binary-resources

    IIRC,编译器将在构建时通过正确的调整嵌入数据,因此您只需提取它。

    这是一个如何提取数据的示例。

    #include "stdafx.h"
    #include "resource.h"
    #include <iostream>
    #include <fstream>
    #include <iterator>
    #include <vector>
    #include <Windows.h>
    #include <shellapi.h>
    
    using namespace std;
    
    void extract_bin_resource(std::wstring strCustomResName, int nResourceId, std::string strOutputPath)
    {
        HGLOBAL hResourceLoaded;   // handle to loaded resource
        HRSRC   hRes;              // handle/ptr to res. info.
        char    *lpResLock;        // pointer to resource data
        DWORD   dwSizeRes;
        std::string strOutputLocation;
        std::string strAppLocation;
    
        hRes = FindResource(NULL, MAKEINTRESOURCE(nResourceId), strCustomResName.c_str());
    
        hResourceLoaded = LoadResource(NULL, hRes);
        lpResLock = (char *)LockResource(hResourceLoaded);
        dwSizeRes = SizeofResource(NULL, hRes);
    
        std::ofstream outputFile(strOutputPath.c_str(), std::ios::binary);
        outputFile.write((const char *)lpResLock, dwSizeRes);
        outputFile.close();
    }
    
    int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
        // Extract the bundled installer
        extract_bin_resource(L"MSI", IDR_MSI1, "installer.msi");
    
        // Execute the installer
        SHELLEXECUTEINFO ShExecInfo = { 0 };
        ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
        ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ShExecInfo.hwnd = NULL;
        ShExecInfo.lpVerb = NULL;
        ShExecInfo.lpFile = L"msiexec.exe";
        ShExecInfo.lpParameters = L"/i installer.msi";
        ShExecInfo.lpDirectory = NULL;
        ShExecInfo.nShow = SW_SHOW;
        ShExecInfo.hInstApp = NULL;
        ShellExecuteEx(&ShExecInfo);
        WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
    
        // Delete the installer
        DeleteFile(L"installer.msi");
    
        return 0;
    }
    

    【讨论】:

    • 对于 52mb 的文件,这会增加 10mb 的开销。知道如何减少这种情况吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多