#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 修复DLL加载失败的专用构建脚本 专门解决pandas._libs.window.aggregations DLL问题 """ import sys import subprocess import platform import site from pathlib import Path def get_pandas_libs_path(): """获取pandas库文件路径""" try: import pandas pandas_path = Path(pandas.__file__).parent libs_path = pandas_path / '_libs' return libs_path except ImportError: return None def create_dll_fix_spec(): """创建修复DLL问题的spec文件""" # 获取pandas库路径 pandas_libs = get_pandas_libs_path() if not pandas_libs or not pandas_libs.exists(): print("❌ 无法找到pandas库路径") return None print(f"✅ 找到pandas库路径: {pandas_libs}") # 查找所有.pyd文件(Windows DLL) pyd_files = list(pandas_libs.glob('**/*.pyd')) print(f"✅ 找到 {len(pyd_files)} 个pandas DLL文件") # 构建binaries列表 binaries_list = [] for pyd_file in pyd_files: rel_path = pyd_file.relative_to(pandas_libs.parent) binaries_list.append(f"(r'{pyd_file}', r'{rel_path.parent}')") binaries_str = ',\n '.join(binaries_list) spec_content = f'''# -*- mode: python ; coding: utf-8 -*- # 专门修复pandas DLL加载问题的配置 import sys from pathlib import Path block_cipher = None a = Analysis( ['seat_allocation_system.py'], pathex=[], binaries=[ # 手动包含所有pandas DLL文件 {binaries_str} ], datas=[], hiddenimports=[ # 核心模块 'pandas', 'numpy', 'openpyxl', # pandas核心库(必须) 'pandas._libs', 'pandas._libs.lib', 'pandas._libs.hashtable', 'pandas._libs.tslib', 'pandas._libs.algos', 'pandas._libs.join', 'pandas._libs.index', 'pandas._libs.internals', 'pandas._libs.writers', 'pandas._libs.parsers', 'pandas._libs.testing', 'pandas._libs.sparse', 'pandas._libs.reduction', 'pandas._libs.ops', 'pandas._libs.missing', 'pandas._libs.groupby', 'pandas._libs.reshape', # pandas时间序列库 'pandas._libs.tslibs', 'pandas._libs.tslibs.base', 'pandas._libs.tslibs.ccalendar', 'pandas._libs.tslibs.conversion', 'pandas._libs.tslibs.dtypes', 'pandas._libs.tslibs.fields', 'pandas._libs.tslibs.nattype', 'pandas._libs.tslibs.np_datetime', 'pandas._libs.tslibs.offsets', 'pandas._libs.tslibs.parsing', 'pandas._libs.tslibs.period', 'pandas._libs.tslibs.strptime', 'pandas._libs.tslibs.timedeltas', 'pandas._libs.tslibs.timestamps', 'pandas._libs.tslibs.timezones', 'pandas._libs.tslibs.tzconversion', 'pandas._libs.tslibs.vectorized', # pandas窗口函数库(关键!) 'pandas._libs.window', 'pandas._libs.window.aggregations', 'pandas._libs.window.indexers', # numpy核心 'numpy.core._methods', 'numpy.core._dtype_ctypes', 'numpy.core.multiarray', 'numpy.core.umath', # 其他必要模块 'ctypes.util', 'pkg_resources.py2_warn', 'encodings.utf_8', 'encodings.gbk', # openpyxl 'openpyxl.workbook', 'openpyxl.worksheet', 'openpyxl.styles', ], hookspath=[], hooksconfig={{}}, runtime_hooks=[], excludes=[ 'matplotlib', 'scipy', 'IPython', 'jupyter', 'tkinter', 'PyQt5', 'PyQt6', 'PIL', 'cv2', 'sklearn', 'tensorflow', 'torch', ], 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='座位分配系统_修复版', debug=False, bootloader_ignore_signals=False, strip=False, upx=False, # 禁用UPX压缩,避免DLL问题 upx_exclude=[], runtime_tmpdir=None, console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) ''' spec_file = Path('dll_fix.spec') with open(spec_file, 'w', encoding='utf-8') as f: f.write(spec_content) print(f"✅ 创建DLL修复spec文件: {spec_file}") return spec_file def build_with_dll_fix(): """使用DLL修复配置构建""" print("=" * 60) print("DLL修复构建") print("=" * 60) # 检查环境 if platform.system() != 'Windows': print("❌ 此脚本仅适用于Windows") return False print(f"✅ 系统: {platform.system()} {platform.release()}") # 检查主文件 main_file = Path('seat_allocation_system.py') if not main_file.exists(): print("❌ 未找到主程序文件") return False # 创建修复spec文件 spec_file = create_dll_fix_spec() if not spec_file: return False # 清理旧文件 dist_dir = Path('dist') if dist_dir.exists(): import shutil shutil.rmtree(dist_dir) print("✅ 清理dist目录") # 构建命令 cmd = [ sys.executable, '-m', 'PyInstaller', '--clean', '--noconfirm', '--log-level=WARN', # 减少输出 str(spec_file) ] print(f"\n执行命令: {' '.join(cmd)}") print("开始DLL修复构建...") try: # 执行构建 result = subprocess.run( cmd, capture_output=True, text=True, encoding='utf-8', errors='ignore' ) # 显示结果 if result.returncode == 0: print("✅ DLL修复构建成功!") # 检查生成的文件 exe_path = Path('dist/座位分配系统_修复版.exe') if exe_path.exists(): size_mb = exe_path.stat().st_size / (1024 * 1024) print(f"✅ 生成文件: {exe_path}") print(f"✅ 文件大小: {size_mb:.1f} MB") # 测试运行 print("\n🧪 测试运行...") test_cmd = [str(exe_path), '--help'] try: test_result = subprocess.run( test_cmd, capture_output=True, text=True, timeout=10 ) if test_result.returncode == 0: print("✅ 程序可以正常启动") else: print("⚠️ 程序启动有问题,但文件已生成") except subprocess.TimeoutExpired: print("⚠️ 测试超时,但文件已生成") except Exception as e: print(f"⚠️ 测试失败: {e}") return True else: print("❌ 未找到生成的exe文件") return False else: print("❌ DLL修复构建失败!") print("错误输出:") print(result.stderr) return False except Exception as e: print(f"❌ 构建出错: {e}") return False def main(): """主函数""" print("🔧 pandas DLL加载失败修复工具") print("专门解决: ImportError: DLL load failed while importing aggregations") print() success = build_with_dll_fix() if success: print("\n🎉 DLL修复构建完成!") print("可执行文件: dist/座位分配系统_修复版.exe") print("\n💡 如果仍有问题,请尝试:") print("1. 在目标机器上安装 Visual C++ Redistributable") print("2. 确保目标机器有相同的Windows版本") else: print("\n❌ DLL修复构建失败!") print("请检查pandas安装是否完整") input("\n按Enter键退出...") if __name__ == '__main__': main()