Files
dtm-py-all/dtmgtApp.spec

207 lines
6.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

# -*- mode: python ; coding: utf-8 -*-
import os
import sys
from PyInstaller.utils.hooks import collect_all, collect_submodules, collect_dynamic_libs
block_cipher = None
# 获取项目根目录的绝对路径
root_dir = os.path.abspath(SPECPATH)
# 收集 UI 目录下的所有子模块
ui_hiddenimports = collect_submodules('UI')
# 收集 tkinter 的所有内容(数据文件、二进制、子模块)
tkinter_datas = []
tkinter_binaries = []
tkinter_hiddenimports = []
try:
from PyInstaller.utils.hooks import collect_all
tk_datas, tk_binaries, tk_hiddenimports = collect_all('tkinter')
tkinter_datas.extend(tk_datas)
tkinter_binaries.extend(tk_binaries)
tkinter_hiddenimports.extend(tk_hiddenimports)
print(f"Collected tkinter: {len(tk_datas)} datas, {len(tk_binaries)} binaries, {len(tk_hiddenimports)} hiddenimports")
except Exception as e:
print(f"Warning: Could not collect tkinter: {e}")
# 如果自动收集失败,手动添加
tkinter_hiddenimports = ['tkinter', 'tkinter.ttk', '_tkinter', 'tkinter.constants']
# 收集 SSL 相关的动态库
ssl_datas = []
ssl_binaries = []
try:
# 收集 pymodbus 的所有依赖
pymodbus_datas, pymodbus_binaries, pymodbus_hiddenimports = collect_all('pymodbus')
ssl_datas.extend(pymodbus_datas)
ssl_binaries.extend(pymodbus_binaries)
except:
pymodbus_hiddenimports = []
try:
# 收集 ssl 模块的依赖
import ssl as ssl_module
ssl_path = os.path.dirname(ssl_module.__file__)
# 添加 Python 安装目录下的 DLLs
python_dir = os.path.dirname(sys.executable)
dll_dir = os.path.join(python_dir, 'DLLs')
# 查找并添加 SSL 相关的 DLL 文件
for dll_name in ['libcrypto-1_1-x64.dll', 'libssl-1_1-x64.dll', 'libcrypto-3-x64.dll', 'libssl-3-x64.dll']:
dll_path = os.path.join(dll_dir, dll_name)
if os.path.exists(dll_path):
ssl_binaries.append((dll_path, '.'))
print(f"Found SSL DLL: {dll_path}")
# 检查 Conda 环境的 Library/bin 目录
conda_prefix = os.environ.get('CONDA_PREFIX')
if conda_prefix:
conda_dll_dir = os.path.join(conda_prefix, 'Library', 'bin')
if os.path.exists(conda_dll_dir):
for dll_name in ['libcrypto-1_1-x64.dll', 'libssl-1_1-x64.dll', 'libcrypto-3-x64.dll', 'libssl-3-x64.dll']:
dll_path = os.path.join(conda_dll_dir, dll_name)
if os.path.exists(dll_path):
ssl_binaries.append((dll_path, '.'))
print(f"Found Conda SSL DLL: {dll_path}")
# 添加 _ssl.pyd 和 _hashlib.pyd
for pyd_name in ['_ssl.pyd', '_hashlib.pyd']:
pyd_path = os.path.join(dll_dir, pyd_name)
if os.path.exists(pyd_path):
ssl_binaries.append((pyd_path, '.'))
print(f"Found PYD: {pyd_path}")
except Exception as e:
print(f"Warning: Could not collect SSL binaries: {e}")
a = Analysis(
['dtmgtApp.py'],
pathex=[root_dir],
binaries=ssl_binaries + tkinter_binaries, # 添加 tkinter 二进制文件
datas=[
# 包含 web 资源文件
('web', 'web'),
# 包含整个 UI 目录
('UI', 'UI'),
# 包含数据库文件
('db', 'db'),
# 添加 SSL 数据文件
*ssl_datas,
# 添加 tkinter 数据文件
*tkinter_datas,
],
hiddenimports=[
# Flask 和相关依赖
'flask',
'flask_cors',
'eel',
# PyQt5 相关
'PyQt5',
'PyQt5.QtCore',
'PyQt5.QtGui',
'PyQt5.QtWidgets',
'PyQt5.QtSql',
# SSL 和加密相关
'ssl',
'_ssl',
'hashlib',
'_hashlib',
# UI 模块(使用自动收集)
*ui_hiddenimports,
# pymodbus 相关(使用自动收集)
*pymodbus_hiddenimports,
# tkinter 相关(使用自动收集,包括所有子模块)
*tkinter_hiddenimports,
'tkinter',
'tkinter.ttk',
'_tkinter',
'tkinter.constants',
'tkinter.filedialog',
# openpyxl 相关Excel导出功能
'openpyxl',
'openpyxl.styles',
'openpyxl.utils',
'openpyxl.cell',
'openpyxl.worksheet',
'openpyxl.workbook',
'openpyxl.reader',
'openpyxl.writer',
'et_xmlfile',
# 其他依赖
'websockets',
'serial',
'pymodbus',
'pymodbus.client',
'pymodbus.client.serial',
'pymodbus.client.tcp',
'pymodbus.transport',
'pymodbus.transport.transport',
'keyboard',
'sqlite3',
'multiprocessing',
'api_route',
'dtMachineService',
'modbus_server',
'utils',
'Observable',
'mhi_plc',
'modbus_plc',
'dtMachine_modbus',
'dtMachine_mhi',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[
# 排除 macOS 相关模块
'serial.tools.list_ports_osx',
# 排除不需要的 SQL 驱动(保留 SQLite
'PyQt5.QtDBus',
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure)
# 过滤掉不需要的 PyQt5 SQL 驱动插件(保留 SQLite
a.binaries = [x for x in a.binaries if not (
'qsqlpsql' in x[0] or # PostgreSQL 驱动
'qsqlmysql' in x[0] or # MySQL 驱动
'qsqlodbc' in x[0] # ODBC 驱动
)]
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='dtmgtApp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False, # 隐藏CMD窗口日志输出已重定向到文件
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=None, # 可以添加ico图标
)