• Windows平台下将exe及其dll封包到新的exe


    〇、项目需求

    通过exe进行交付时,但通常会使用一些第三方库,如果对方没有相应环境或环境配置不同或版本不同,那就不能愉快地执行程序了。所以就需要把用到的dll和exe一起打包,但这样稍显臃肿和不便。因为用到的dll基本上是第三库的,几乎不会自己去更新,所以不如将dll和exe封包到一起。

    一、生成 exe

    Release 下生成原始exe,注意在这一步要把接API暴露出来。

    二、通过 Dependencies 寻找所需dll

    Dependencies 提供GUI和程序调用接口。
    其GUI打开是这个样子,使用也很简单,把exe拖进去就行了。
    在这里插入图片描述

    但是其GUI分析结果没有输出选项,所以这里我选择使用其调用接口,通过通过命令行找到exe所依赖的dll,并将输出另存为txt。

    如:

     .\Dependencies.exe -imports "D:\Project\CPP_Project\PCL_align\x64\Release\PCL_align.exe" -modules >>"D:\Project\CPP_Project\PCL_align\x64\dll.txt"
    
    • 1

    Dependencies下载安装后,安装目录下就有 Dependencies.exe 和 DependenciesGUI.exe。

    输出的txt大概长这样子

    [ROOT] PCL_align.exe : D:\Project\CPP_Project\PCL_align\x64\Release\PCL_align.exe 
    [ApiSetSchema] api-ms-win-crt-heap-l1-1-0.dll : C:\Windows\system32\ucrtbase.dll 
    ......
    [ApiSetSchema] api-ms-win-devices-query-l1-1-1.dll : C:\Windows\system32\cfgmgr32.dll 
    [ApiSetSchema] ext-ms-win-winrt-storage-l1-2-1.dll : C:\Windows\system32\windows.storage.dll 
    [WellKnownDlls] KERNEL32.dll : C:\Windows\system32\kernel32.dll 
    ......
    [WellKnownDlls] COMDLG32.dll : C:\Windows\system32\COMDLG32.dll 
    [WellKnownDlls] setupapi.dll : C:\Windows\system32\Setupapi.dll 
    [WellKnownDlls] PSAPI.DLL : C:\Windows\system32\PSAPI.DLL 
    [WindowsFolder] MSVCP140.dll : C:\Windows\system32\MSVCP140.dll 
    [WindowsFolder] VCRUNTIME140_1.dll : C:\Windows\system32\VCRUNTIME140_1.dll 
    [WindowsFolder] VCRUNTIME140.dll : C:\Windows\system32\VCRUNTIME140.dll 
    ......
    [WindowsFolder] OPENGL32.dll : C:\Windows\system32\OPENGL32.dll 
    [WindowsFolder] GLU32.dll : C:\Windows\system32\GLU32.dll 
    [Environment] pcl_common.dll : D:\Program Files (x86)\PCL 1.13.0\bin\pcl_common.dll 
    [Environment] pcl_filters.dll : D:\Program Files (x86)\PCL 1.13.0\bin\pcl_filters.dll 
    ......
    [Environment] vtkFiltersHyperTree-9.2.dll : D:\Program Files (x86)\PCL 1.13.0\3rdParty\VTK\bin\vtkFiltersHyperTree-9.2.dll 
    [Environment] vtkloguru-9.2.dll : D:\Program Files (x86)\PCL 1.13.0\3rdParty\VTK\bin\vtkloguru-9.2.dll 
    [Environment] vtkkissfft-9.2.dll : D:\Program Files (x86)\PCL 1.13.0\3rdParty\VTK\bin\vtkkissfft-9.2.dll 
    [NOT_FOUND] ext-ms-win-shell32-shellcom-l1-1-0.dll :  
    [NOT_FOUND] ext-ms-win32-subsystem-query-l1-1-0.dll :  
    [NOT_FOUND] ext-ms-win-security-chambers-l1-1-0.dll :  
    ......
    [NOT_FOUND] ext-ms-win-dx-ddraw-l1-1-0.dll :  
    [NOT_FOUND] api-ms-win-core-psapi-obsolete-l1-1-0.dll :  
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    三、将所需 dll 复制到 exe 同级目录下

    3.1 通过 python 脚本自动处理

    主要关注 [Environment] 和 项目中的dll。

    # File      :Extract_dll_to_floder.py
    # Auther    :WooChi
    # Time      :2023/10/11
    # Version   :1.0
    # Function  :
    
    import os
    import shutil
    
    def Move_File_to_Folder(txtPath,tgtPath):
        with open(txtPath, 'r') as file:
            count=0
            for line in file:
                if(line[:13]=="[Environment]"):
                    count+=1
                    # 使用":"将字符串分割成两部分
                                    parts = line.split(" : ")
                    dllpath = parts[1][:-2]
                    dst=os.path.join(tgtPath, os.path.basename(dllpath))
                    if not os.path.exists(dst):
                        shutil.copyfile(dllpath , dst)
                    else:
                        print(f"File {dst} already exists. Skipping.")
                        
    
    if __name__ == '__main__':
        txtPath=r"D:\Project\CPP_Project\PCL_align\x64\dll.txt"
        tgtPath=r"D:\Project\CPP_Project\PCL_align\x64\Release"
    
        Move_File_to_Folder(txtPath,tgtPath)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    3.2 使用 Everthing 搜索特定dll

    少数情况下,[NOT_FOUND] 中也会出现所需dll,这时候可以用 Everthing 搜索相应 dll 再复制到exe同级目录下就ok了。

    Everthing 除了GUI外,还有可供调用的接口,但是需要完整安装 Evething,而我使用的是单文件版,这里就不展开了,具体可参考这里

    3.3 验证 dll 是否完备

    在exe所在目录下双击exe或通过cmd执行exe,若一闪而过、正常运行,则dll已完备,若弹出找不到***.dll,说明还缺相应的dll。

    四、使用 Enigma Virtual Box 对 dll 和 exe 进行封包

    4.1 下载安装 Enigma Virtual Box

    官网下载然后安装,不多说了。

    4.2 开始执行封包

    1. 打开 Enigma Virtual Box

    2. 选择待封包程序和新程序名字(默认_boxed.exe)
      在这里插入图片描述

    3. 左下角增加递归文件夹,选择 dll 所在目录,也就是之前提到的 exe 同级目录,在对话框中确定。
      在这里插入图片描述

    4. 在树形结构里,把不需要的文件移除(除了dll外的其他文件对移除)。
      在这里插入图片描述

    5. 点击右下角文件选择,勾选压缩文件选项。
      在这里插入图片描述

    6. 右下角,点击执行封包,很快就大功告成。
      在这里插入图片描述

    五、验证封包后的 exe

    1. 将封包的exe文件移动到其他目录下通过cmd执行相应命令进行验证。
    2. 到其他设备进行验证。

    打完收工!

  • 相关阅读:
    微服务实战系列之Gateway
    Django实现统一包装接口返回值数据格式
    golang操作etcd
    c#设计模式-行为型模式 之 解释器模式
    网易云Android面试拿offer分享:Java多线程+View+flutter+算法题
    【深入理解Kotlin协程】Google的工程师们是这样理解Flow的?
    新能源中期财报:有人上天入地有人还在苦苦挣扎
    Day01 SpringBoot第一次笔记---运维实用篇
    SANSAN每周新鲜事|OPC UA 数据采集,你真的了解吗?
    链上信使协议AMOP
  • 原文地址:https://blog.csdn.net/m0_50910915/article/details/133774076