Files
shuidrop_gui/quick_build.py

300 lines
9.4 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
快速打包脚本 - 避免spec文件缩进问题
"""
import os
import subprocess
import shutil
def clean_build():
"""清理构建目录"""
print("🧹 清理旧的构建文件...")
# 跳过进程结束步骤,避免影响当前脚本运行
print("🔄 跳过进程结束步骤(避免脚本自终止)...")
# 等待少量时间确保文件句柄释放
import time
print("⏳ 等待文件句柄释放...")
time.sleep(0.5)
dirs_to_clean = ['dist', 'build']
for dir_name in dirs_to_clean:
print(f"🔍 检查目录: {dir_name}")
if os.path.exists(dir_name):
try:
print(f"🗑️ 正在删除: {dir_name}")
shutil.rmtree(dir_name)
print(f"✅ 已删除: {dir_name}")
except PermissionError as e:
print(f"⚠️ {dir_name} 被占用,尝试强制删除... 错误: {e}")
try:
subprocess.run(['rd', '/s', '/q', dir_name],
shell=True, check=True)
print(f"✅ 强制删除成功: {dir_name}")
except Exception as e2:
print(f"❌ 无法删除 {dir_name}: {e2}")
print("💡 请手动删除或运行 force_clean_dist.bat")
except Exception as e:
print(f"❌ 删除 {dir_name} 时出错: {e}")
else:
print(f" {dir_name} 不存在,跳过")
print("✅ 清理阶段完成")
def build_with_command():
"""使用命令行参数直接打包"""
print("🚀 开始打包...")
cmd = [
'pyinstaller',
'--name=main',
'--onedir', # 相当于 --exclude-binaries
'--windowed', # 相当于 -w
'--add-data=config.py;.',
'--add-data=exe_file_logger.py;.',
'--add-data=Utils/PythonNew32;Utils/PythonNew32',
'--add-data=Utils/JD;Utils/JD',
'--add-data=Utils/Dy;Utils/Dy',
'--add-data=Utils/Pdd;Utils/Pdd',
'--add-data=Utils/QianNiu;Utils/QianNiu',
'--add-data=Utils/message_models.py;Utils',
'--add-data=Utils/__init__.py;Utils',
'--add-data=WebSocket;WebSocket',
'--add-data=static;static',
'--add-binary=Utils/PythonNew32/SaiNiuApi.dll;Utils/PythonNew32',
'--add-binary=Utils/PythonNew32/SaiNiuSys.dll;Utils/PythonNew32',
'--add-binary=Utils/PythonNew32/SaiNiuServer.dll;Utils/PythonNew32',
'--add-binary=Utils/PythonNew32/python32.exe;Utils/PythonNew32',
'--add-binary=Utils/PythonNew32/python313.dll;Utils/PythonNew32',
'--add-binary=Utils/PythonNew32/vcruntime140.dll;Utils/PythonNew32',
'--hidden-import=PyQt5.QtCore',
'--hidden-import=PyQt5.QtGui',
'--hidden-import=PyQt5.QtWidgets',
'--hidden-import=websockets',
'--hidden-import=asyncio',
'--hidden-import=Utils.QianNiu.QianNiuUtils',
'--hidden-import=Utils.JD.JdUtils',
'--hidden-import=Utils.Dy.DyUtils',
'--hidden-import=Utils.Pdd.PddUtils',
'--hidden-import=WebSocket.backend_singleton',
'--hidden-import=WebSocket.BackendClient',
'main.py'
]
try:
print(f"执行命令: {' '.join(cmd[:5])}... (共{len(cmd)}个参数)")
result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8')
if result.returncode == 0:
print("✅ 打包成功!")
print("📁 打包结果: dist/main/")
# 重命名目录
if os.path.exists('dist/main'):
try:
if os.path.exists('dist/MultiPlatformGUI'):
shutil.rmtree('dist/MultiPlatformGUI')
os.rename('dist/main', 'dist/MultiPlatformGUI')
print("✅ 已重命名为: dist/MultiPlatformGUI/")
except Exception as e:
print(f"⚠️ 重命名失败: {e}")
print("💡 可以手动重命名: dist/main -> dist/MultiPlatformGUI")
print("📁 当前可用路径: dist/main/")
# 创建使用说明
try:
create_usage_guide()
except:
create_usage_guide_fallback()
return True
else:
print("❌ 打包失败")
if result.stderr:
print("错误信息:")
print(result.stderr)
return False
except Exception as e:
print(f"❌ 打包过程出错: {e}")
return False
def create_usage_guide():
"""创建使用说明"""
guide_content = r"""# 多平台客服GUI使用说明
## 🚀 运行方式
```
cd dist/MultiPlatformGUI
.\main.exe
```
## 📝 支持平台
- 千牛 (淘宝)
- 京东 (JD)
- 抖音 (DY)
- 拼多多 (PDD)
## 🎯 特点
- 支持多平台同时监听
- 无平台间冲突
- 自动生成日志文件
## 📁 文件结构
```
MultiPlatformGUI/
├── main.exe # 主程序
├── qianniu_exe_*.log # 运行日志
└── _internal/ # 程序依赖文件
├── Utils/
│ ├── PythonNew32/ # 千牛DLL文件
│ ├── JD/ # 京东模块
│ ├── Dy/ # 抖音模块
│ └── Pdd/ # 拼多多模块
└── ...
```
"""
try:
with open('dist/MultiPlatformGUI/使用说明.txt', 'w', encoding='utf-8') as f:
f.write(guide_content)
print("✅ 已生成使用说明文件")
except:
print("⚠️ 使用说明生成失败")
def create_usage_guide_fallback():
"""备用使用说明生成"""
guide_content = r"""# 多平台客服GUI使用说明
## 🚀 运行方式
```
cd dist/main
.\main.exe
```
## 📝 支持平台
- 千牛 (淘宝)
- 京东 (JD)
- 抖音 (DY)
- 拼多多 (PDD)
## 🎯 特点
- 支持多平台同时监听
- 无平台间冲突
- 自动生成日志文件
"""
try:
with open('dist/main/使用说明.txt', 'w', encoding='utf-8') as f:
f.write(guide_content)
print("✅ 已生成使用说明文件 (备用路径)")
except:
print("⚠️ 使用说明生成失败")
def verify_result():
"""验证打包结果"""
print("\n🔍 验证打包结果...")
# 先检查MultiPlatformGUI再检查main目录
base_dirs = ["dist/MultiPlatformGUI", "dist/main"]
for base_dir in base_dirs:
if os.path.exists(base_dir):
exe_path = f"{base_dir}/main.exe"
dll_path = f"{base_dir}/_internal/Utils/PythonNew32/SaiNiuApi.dll"
if os.path.exists(exe_path):
size = os.path.getsize(exe_path)
print(f"✅ 主程序: {exe_path} ({size:,} bytes)")
if os.path.exists(dll_path):
dll_size = os.path.getsize(dll_path)
print(f"✅ 千牛DLL: SaiNiuApi.dll ({dll_size:,} bytes)")
print(f"📁 有效路径: {base_dir}/")
print("✅ 验证通过")
return True
else:
print("❌ 千牛DLL不存在")
else:
print(f"{exe_path} 不存在")
print("❌ 未找到有效的打包结果")
return False
def main():
"""主函数"""
print("🔥 多平台客服GUI快速打包工具")
print("=" * 60)
try:
# 检查依赖
print("🔍 检查打包依赖...")
try:
import subprocess
result = subprocess.run(['pyinstaller', '--version'],
capture_output=True, text=True, check=False)
if result.returncode == 0:
print(f"✅ PyInstaller 版本: {result.stdout.strip()}")
else:
print("❌ PyInstaller 未安装或不可用")
print("💡 请运行: pip install pyinstaller")
return False
except Exception as e:
print(f"❌ 检查PyInstaller时出错: {e}")
return False
# 清理
print("\n📍 开始清理阶段...")
clean_build()
print("📍 清理阶段完成")
# 打包
print("\n📍 开始打包阶段...")
if not build_with_command():
print("❌ 打包阶段失败")
return False
print("📍 打包阶段完成")
# 验证
print("\n📍 开始验证阶段...")
if not verify_result():
print("❌ 验证阶段失败")
return False
print("📍 验证阶段完成")
print("\n" + "=" * 60)
print("🎉 打包完成!")
# 智能显示可用路径
if os.path.exists("dist/MultiPlatformGUI"):
print("📁 打包结果: dist/MultiPlatformGUI/")
print("🚀 运行方式: cd dist/MultiPlatformGUI && .\\main.exe")
elif os.path.exists("dist/main"):
print("📁 打包结果: dist/main/")
print("🚀 运行方式: cd dist/main && .\\main.exe")
print("💡 提示: 可手动重命名为 MultiPlatformGUI")
print("=" * 60)
return True
except Exception as e:
print(f"❌ 打包失败: {e}")
return False
if __name__ == "__main__":
success = main()
if success:
print("\n✅ 可以开始测试了!")
else:
print("\n❌ 请检查错误信息并重试")