Open Suvan-L opened 10 months ago
cd E:\gitee-procjet\iot-automatic-pet-feeding\python\wxhelper\py\release 1. 进入项目目录,执行 pyi-makespec .\start_tcp_server_19099.py - 此处会生成 spec 文件,我们后续将进行修改 - 【注意】不要加 -F,表示所有依赖都将拷贝到 dist 目录下 2. 参考我的 start_tcp_server_19099.spec 文件 1. 设置 exe 程序名称 2. 主动脚本拷贝配置文件目录 3. 指定需要手动添加依赖库的文件 - 解决打包成功,但执行 exe 失败问题,例如:FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\liush\\AppData\\Local\\Temp\\_MEI214962\\borax\\calendars\\FestivalData.csv' 4. 声明项目内所有 python 脚本 3. 执行打包脚本 pyinstaller .\start_tcp_server_19099.spec - 中途可能要输入 y 4. 启动程序 .\dist\start_tcp_server_19099\start_tcp_server_19099.exe
# -*- mode: python ; coding: utf-8 -*- from PyInstaller.building.api import PYZ, EXE, COLLECT from PyInstaller.building.build_main import Analysis import shutil import os # 1. 设置 exe 程序名称 exeName = "start_tcp_server_19099" # 2. 主动脚本拷贝配置文件目录 # (因为 datas 参数会将资源文件都拷贝到 dist/_internal/ 路径下,有些程序的搜索路径会不行,所以此处进行脚本拷贝) copyDirectory_list = [ ("config_file", 'dist\\start_tcp_server_19099\\config_file') ] # 3. 指定需要手动添加依赖库的文件 # (第三方库含有静态文件,需要在下面目录,编写 hook-xxxx.py 主动添加依赖) hookspath = "PyInstaller-hookspath\\" if not os.path.exists(hookspath): # 判断是否存在文件夹如果不存在则创建为文件夹 os.makedirs(hookspath) # 导入模块名称 importModuleName_list = [ "borax" ] # 生成文件,这里是固定模板的,所以直接代码生成 for moduleName in importModuleName_list: fileName = hookspath + "hook-" + moduleName + ".py" if os.path.exists(fileName): print(fileName, " 文件已存在,不重新创建") continue # 追加写入内容到文件 with open(fileName, "a") as file: file.write("from PyInstaller.utils.hooks import collect_data_files\n") file.write("datas = collect_data_files('" + moduleName + "')\n") print("已生成 ", fileName, " 文件!") # ==================新建 a 变量,分析脚本============================ # 4. 声明项目内所有 python 脚本 a = Analysis( [ 'config.py', 'daily_schedule_task.py', 'file_db.py', 'start_tcp_server_19099.py', 'type_1_handler.py', 'type_3_handler.py', 'type_43_handler.py', 'type_49_handler.py', 'custom_http/__init__.py', 'custom_http/http_ali_ai.py', 'custom_http/http_aliCloudDiskSearch_api.py', 'custom_http/http_chatgpt_ai.py', 'custom_http/http_eastmoney_api.py', 'custom_http/http_gaode_weather_api.py', 'custom_http/http_iflytek_ai.py', 'custom_http/http_iflytek_translation.py', 'custom_http/http_iot_api.py', 'custom_http/http_qqMusicDownload_api.py', 'custom_http/http_wxHelper_client.py', 'custom_http/util_borax.py', 'custom_http/util_cnlunar.py', 'custom_http/util_dailyMusicXmlParse.py', 'custom_http/util_efinance.py' ], pathex=[], binaries=[], datas=[ # 写明所有需要拷贝的静态资源文件(来源路径,目标路的地址) # 注意会全部拷贝到 dist/_internal 路径下所以项目中相对路径可能会有问题 # 所以建议使用上面的 shutil.copytree 进行脚本拷贝 # ('config_file\\*', 'config_file') ], hiddenimports=[], # 针对第三方库,内部含有文件的需要手动添加 hookspath=[hookspath], hooksconfig={}, runtime_hooks=[], excludes=[], noarchive=False, ) # ========================为 a 生成 exe ========================= pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name=exeName, debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) coll = COLLECT( exe, a.binaries, a.datas, strip=False, upx=True, upx_exclude=[], name=exeName, ) # 放到最后,在生成玩 exe 后再执行 for directory in copyDirectory_list: src = directory[0] target = directory[1] if os.path.exists(target): print("目标路径已存在,先执行删除 ", target) shutil.rmtree(target) # 拷贝目录 shutil.copytree(src, target) print("成功拷贝路径 ", src, " 到 ", target)
rem 当遇到确认的时候,自动输入 y echo y |pyinstaller .\start_tcp_server_19099.spec
6.0 进化了很多,主要是所有的打包文件最后都会进入 _internal 文件,有些路径也会改变到 _internal 里。只是我懒得更新文章了。你可以参考下这个我打包脚本:https://github.com/HaujetZhao/CapsWriter-Offline/blob/master/build.spec
1. 整体思路(start_tcp_server_19099.py 是主启动文件)
2. 分享 spec 文件
3. 最终效果
4. 可以写个 bat 脚本,用于自动编译