226 lines
6.9 KiB
Python
226 lines
6.9 KiB
Python
import os
|
|
import sys
|
|
import subprocess
|
|
import shutil
|
|
import glob
|
|
import time
|
|
from PIL import Image, ImageDraw
|
|
|
|
def build_executable():
|
|
"""Build executable with PyInstaller"""
|
|
print("Building LTE Manager executable...")
|
|
|
|
# 尝试终止可能正在运行的LTE_Manager.exe进程
|
|
try:
|
|
print("尝试终止可能正在运行的LTE_Manager.exe进程...")
|
|
subprocess.call("taskkill /F /IM LTE_Manager.exe", shell=True)
|
|
# 等待进程完全终止
|
|
time.sleep(2)
|
|
except Exception as e:
|
|
print(f"终止进程时出错 (这可能是正常的,如果进程不存在): {str(e)}")
|
|
|
|
# 保存数据库文件
|
|
db_backup_dir = "_db_backup_temp"
|
|
db_files = []
|
|
|
|
# 查找用户主目录下的数据库文件
|
|
user_home = os.path.expanduser('~')
|
|
lte_db_dir = os.path.join(user_home, '.LTE')
|
|
user_db_path = os.path.join(lte_db_dir, 'lte_data.db')
|
|
|
|
if os.path.exists("dist") or os.path.exists(user_db_path):
|
|
print("备份数据库文件...")
|
|
# 创建临时备份目录
|
|
if not os.path.exists(db_backup_dir):
|
|
os.makedirs(db_backup_dir)
|
|
|
|
# 查找所有SQLite数据库文件
|
|
dist_db_files = glob.glob("dist/*.db") if os.path.exists("dist") else []
|
|
|
|
# 备份找到的dist目录中的文件
|
|
for db_file in dist_db_files:
|
|
db_filename = os.path.basename(db_file)
|
|
backup_path = os.path.join(db_backup_dir, db_filename)
|
|
print(f"备份数据库 (旧版位置): {db_filename}")
|
|
shutil.copy2(db_file, backup_path)
|
|
|
|
# 备份用户主目录中的数据库
|
|
if os.path.exists(user_db_path):
|
|
backup_path = os.path.join(db_backup_dir, 'lte_data.db')
|
|
print(f"备份数据库 (用户目录): {user_db_path}")
|
|
shutil.copy2(user_db_path, backup_path)
|
|
|
|
# Check if PyInstaller is installed
|
|
try:
|
|
import PyInstaller
|
|
except ImportError:
|
|
print("PyInstaller not found. Installing...")
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "pyinstaller"])
|
|
|
|
# Create spec file
|
|
spec_content = """
|
|
# -*- mode: python ; coding: utf-8 -*-
|
|
|
|
block_cipher = None
|
|
|
|
a = Analysis(
|
|
['main.py'],
|
|
pathex=[],
|
|
binaries=[],
|
|
datas=[
|
|
('default.png', '.'),
|
|
('running.png', '.'),
|
|
('error.png', '.'),
|
|
('README.md', '.'),
|
|
('incoming_call.py', '.'),
|
|
('audio.py', '.')
|
|
],
|
|
hiddenimports=['PyQt5.sip', 'sounddevice', 'numpy'],
|
|
hookspath=[],
|
|
hooksconfig={},
|
|
runtime_hooks=[],
|
|
excludes=[],
|
|
win_no_prefer_redirects=False,
|
|
win_private_assemblies=False,
|
|
cipher=block_cipher,
|
|
noarchive=False,
|
|
)
|
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
|
|
exe = EXE(
|
|
pyz,
|
|
a.scripts,
|
|
a.binaries,
|
|
a.zipfiles,
|
|
a.datas,
|
|
[],
|
|
name='LTE_Manager',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=True,
|
|
upx_exclude=[],
|
|
runtime_tmpdir=None,
|
|
console=False,
|
|
disable_windowed_traceback=False,
|
|
argv_emulation=False,
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
icon='default.png',
|
|
)
|
|
"""
|
|
|
|
with open("lte_manager.spec", "w") as f:
|
|
f.write(spec_content)
|
|
|
|
# Run PyInstaller
|
|
print("Running PyInstaller...")
|
|
try:
|
|
# 等待一秒确保所有进程都释放了文件
|
|
time.sleep(1)
|
|
|
|
# 先检查目标EXE文件是否存在并可以被删除
|
|
target_exe = os.path.join("dist", "LTE_Manager.exe")
|
|
if os.path.exists(target_exe):
|
|
try:
|
|
# 尝试先重命名文件,这是检查文件是否被锁定的一种方法
|
|
temp_name = os.path.join("dist", f"LTE_Manager_old_{int(time.time())}.exe")
|
|
os.rename(target_exe, temp_name)
|
|
# 然后删除重命名后的文件
|
|
os.remove(temp_name)
|
|
print("成功删除旧的可执行文件")
|
|
except Exception as rename_error:
|
|
print(f"无法删除旧的可执行文件: {str(rename_error)}")
|
|
print("尝试使用Python 3.10来构建...")
|
|
# 尝试使用Python 3.10,如果可用
|
|
python310_path = r"G:\Python310\python.exe"
|
|
if os.path.exists(python310_path):
|
|
subprocess.check_call([
|
|
python310_path,
|
|
"-m",
|
|
"PyInstaller",
|
|
"lte_manager.spec",
|
|
"--clean"
|
|
])
|
|
print("使用Python 3.10构建完成")
|
|
build_success = True
|
|
return
|
|
|
|
# 运行PyInstaller
|
|
subprocess.check_call([
|
|
sys.executable,
|
|
"-m",
|
|
"PyInstaller",
|
|
"lte_manager.spec",
|
|
"--clean"
|
|
])
|
|
|
|
print("PyInstaller执行完成")
|
|
build_success = True
|
|
except Exception as e:
|
|
print(f"构建过程中出错: {str(e)}")
|
|
build_success = False
|
|
|
|
# 恢复数据库文件
|
|
if os.path.exists(db_backup_dir):
|
|
print("恢复数据库文件...")
|
|
backups = glob.glob(os.path.join(db_backup_dir, "*.db"))
|
|
|
|
for backup_file in backups:
|
|
db_filename = os.path.basename(backup_file)
|
|
|
|
# 确保用户目录存在
|
|
if not os.path.exists(lte_db_dir):
|
|
os.makedirs(lte_db_dir)
|
|
|
|
# 恢复到用户主目录
|
|
user_db_path = os.path.join(lte_db_dir, db_filename)
|
|
print(f"恢复数据库到用户目录: {user_db_path}")
|
|
shutil.copy2(backup_file, user_db_path)
|
|
|
|
# 为了向后兼容,也恢复到dist目录
|
|
if os.path.exists("dist"):
|
|
dist_path = os.path.join("dist", db_filename)
|
|
print(f"恢复数据库到dist目录: {dist_path}")
|
|
shutil.copy2(backup_file, dist_path)
|
|
|
|
# 删除临时备份目录
|
|
shutil.rmtree(db_backup_dir)
|
|
|
|
# Create a simple README file (if it doesn't exist)
|
|
if not os.path.exists("README.md"):
|
|
with open("README.md", "w") as f:
|
|
f.write("""# LTE Manager
|
|
|
|
一个用于管理LTE模块的应用程序,支持电话和短信功能。
|
|
|
|
## 功能
|
|
|
|
- 电话呼叫管理(拨打/接听电话)
|
|
- 短信管理(发送/接收/解码短信,包括中文)
|
|
- 模块配置和状态监控
|
|
- 串口配置
|
|
- 来电接听对话框
|
|
- PCM音频通话支持
|
|
|
|
## 使用方法
|
|
|
|
1. 连接LTE模块到计算机
|
|
2. 在设置选项卡中配置串口设置
|
|
3. 连接到模块
|
|
4. 使用电话和短信功能
|
|
|
|
## 系统托盘
|
|
|
|
应用程序可以最小化到系统托盘。双击托盘图标可以显示/隐藏主窗口。
|
|
""")
|
|
|
|
if build_success:
|
|
print("Executable built successfully!")
|
|
print("You can find it in the 'dist' folder.")
|
|
else:
|
|
print("构建过程未完成,请检查错误信息。")
|
|
|
|
if __name__ == "__main__":
|
|
build_executable() |