# -*- mode: python ; coding: utf-8 -*- # WindowMsgBot PyInstaller spec文件 # 用法: pyinstaller build/windowmsgbot.spec import os import sys from PyInstaller.utils.hooks import collect_submodules, collect_data_files # 项目根目录 PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(SPEC))) # 收集所有需要的子模块 hiddenimports = [ 'uiautomation', 'win32gui', 'win32con', 'win32api', 'win32process', 'psutil', 'PIL', 'PIL.Image', 'PIL.ImageGrab', 'PIL.ImageEnhance', 'PIL.ImageFilter', 'easyocr', 'numpy', 'torch', 'torchvision', 'sklearn', 'sklearn.feature_extraction.text', 'sklearn.metrics.pairwise', 'jieba', 'customtkinter', 'comtypes', 'comtypes.client', 'win32com', 'win32com.client', 'pythoncom', 'pywintypes', 'ctypes', 'ctypes.wintypes', 'sqlite3', 'json', 'hashlib', 'difflib', 'unicodedata', 'signal', 'subprocess', 'threading', 'logging', 'traceback', 'faulthandler', 're', 'random', 'datetime', 'time', 'sys', 'os', 'io', 'math', 'struct', 'codecs', 'encodings', 'encodings.utf_8', 'encodings.gbk', 'encodings.gb2312', 'encodings.gb18030', ] # 数据文件 datas = [ # 知识库目录 (os.path.join(PROJECT_ROOT, '知识库'), '知识库'), # 偏旁库 (os.path.join(PROJECT_ROOT, 'unicode_radicals.md'), '.'), # 配置文件 (os.path.join(PROJECT_ROOT, 'config.json'), '.'), # EasyOCR worker脚本(作为数据文件,运行时提取) (os.path.join(PROJECT_ROOT, 'easyocr_worker.py'), '.'), # 其他必要文件 (os.path.join(PROJECT_ROOT, 'auto_reply.py'), '.'), (os.path.join(PROJECT_ROOT, 'knowledge_base.py'), '.'), (os.path.join(PROJECT_ROOT, 'config.py'), '.'), (os.path.join(PROJECT_ROOT, 'gui.py'), '.'), ] # 收集easyocr数据文件 easyocr_datas = collect_data_files('easyocr') datas.extend(easyocr_datas) # 分析 a = Analysis( [os.path.join(PROJECT_ROOT, 'main.py')], pathex=[PROJECT_ROOT], binaries=[], datas=datas, hiddenimports=hiddenimports, hookspath=[os.path.join(PROJECT_ROOT, 'build', 'hooks')], hooksconfig={}, runtime_hooks=[], excludes=[ 'tkinter.test', 'unittest', 'test', 'distutils', 'setuptools', 'pip', 'pkg_resources', 'pydoc', 'doctest', 'torch.autograd', 'torch.testing', 'torch.distributed', 'torch.fx', 'torch.jit', 'torch.onnx', 'torch.profiler', 'torch.sparse', 'torch.utils.benchmark', 'torch.utils.bottleneck', 'torch.utils.checkpoint', 'torch.utils.collect_env', 'torch.utils.cpp_extension', 'torch.utils.data', 'torch.utils.deterministic', 'torch.utils.dlpack', 'torch.utils.file_baton', 'torch.utils.hipify', 'torch.utils.jit', 'torch.utils.mobile_optimizer', 'torch.utils.model_zoo', 'torch.utils.show_pickle', 'torch.utils.tensorboard', 'torch.utils.throughput_benchmark', ], noarchive=False, ) # 过滤掉不必要的大文件 a.datas = [d for d in a.datas if not d[0].endswith(('.pyc', '.pyo'))] # PYZ - Python字节码 pyz = PYZ(a.pure) # EXE - 主程序(onedir模式:只放脚本+PYZ,不嵌入binaries/data) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, # onedir关键:不嵌入二进制,交给COLLECT name='WindowMsgBot', debug=False, bootloader_ignore_signals=False, strip=False, upx=False, # UPX对大型DLL(torch/scipy)常出问题,关掉 console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) # COLLECT - 收集所有文件到输出目录 coll = COLLECT( exe, a.binaries, a.datas, strip=False, upx=False, name='WindowMsgBot', )