TableSynthesis/fix_dll_build.py
2025-07-02 20:08:23 +08:00

303 lines
8.3 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.

#!/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()