修改打包交脚本
This commit is contained in:
parent
8a103224b5
commit
1e9925a9f2
42
fix_dll_build.bat
Normal file
42
fix_dll_build.bat
Normal file
@ -0,0 +1,42 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
echo ============================================================
|
||||
echo pandas DLL修复构建脚本
|
||||
echo 专门解决: ImportError: DLL load failed while importing aggregations
|
||||
echo ============================================================
|
||||
echo.
|
||||
|
||||
echo 检查Python环境...
|
||||
python --version
|
||||
if errorlevel 1 (
|
||||
echo ❌ Python未安装或未添加到PATH
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo 检查pandas安装...
|
||||
python -c "import pandas; print(f'✅ pandas版本: {pandas.__version__}')"
|
||||
if errorlevel 1 (
|
||||
echo ❌ pandas未安装
|
||||
echo 正在安装pandas...
|
||||
pip install pandas
|
||||
)
|
||||
|
||||
echo.
|
||||
echo 检查PyInstaller...
|
||||
python -c "import PyInstaller; print('✅ PyInstaller已安装')"
|
||||
if errorlevel 1 (
|
||||
echo ❌ PyInstaller未安装
|
||||
echo 正在安装PyInstaller...
|
||||
pip install pyinstaller
|
||||
)
|
||||
|
||||
echo.
|
||||
echo 开始DLL修复构建...
|
||||
python fix_dll_build.py
|
||||
|
||||
echo.
|
||||
echo 构建完成!
|
||||
echo 如果成功,可执行文件位于: dist\座位分配系统_修复版.exe
|
||||
pause
|
302
fix_dll_build.py
Normal file
302
fix_dll_build.py
Normal file
@ -0,0 +1,302 @@
|
||||
#!/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()
|
169
test_pandas_dll.py
Normal file
169
test_pandas_dll.py
Normal file
@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试pandas DLL模块加载
|
||||
专门检查可能导致PyInstaller问题的模块
|
||||
"""
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
|
||||
def test_pandas_core():
|
||||
"""测试pandas核心模块"""
|
||||
print("=" * 50)
|
||||
print("测试pandas核心模块")
|
||||
print("=" * 50)
|
||||
|
||||
modules_to_test = [
|
||||
'pandas',
|
||||
'pandas._libs',
|
||||
'pandas._libs.lib',
|
||||
'pandas._libs.hashtable',
|
||||
'pandas._libs.algos',
|
||||
'pandas._libs.index',
|
||||
'pandas._libs.writers',
|
||||
'pandas._libs.parsers',
|
||||
'pandas._libs.tslibs',
|
||||
'pandas._libs.tslibs.base',
|
||||
'pandas._libs.window',
|
||||
'pandas._libs.window.aggregations', # 关键模块!
|
||||
'pandas._libs.window.indexers',
|
||||
]
|
||||
|
||||
success_count = 0
|
||||
for module in modules_to_test:
|
||||
try:
|
||||
__import__(module)
|
||||
print(f"✅ {module}")
|
||||
success_count += 1
|
||||
except ImportError as e:
|
||||
print(f"❌ {module}: {e}")
|
||||
except Exception as e:
|
||||
print(f"⚠️ {module}: {e}")
|
||||
|
||||
print(f"\n成功加载: {success_count}/{len(modules_to_test)} 个模块")
|
||||
return success_count == len(modules_to_test)
|
||||
|
||||
def test_pandas_functionality():
|
||||
"""测试pandas基本功能"""
|
||||
print("\n" + "=" * 50)
|
||||
print("测试pandas基本功能")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
# 创建测试数据
|
||||
df = pd.DataFrame({
|
||||
'A': [1, 2, 3, 4, 5],
|
||||
'B': [10, 20, 30, 40, 50]
|
||||
})
|
||||
|
||||
print("✅ DataFrame创建成功")
|
||||
|
||||
# 测试窗口函数(这是出错的关键)
|
||||
result = df['A'].rolling(window=2).sum()
|
||||
print("✅ rolling窗口函数正常")
|
||||
|
||||
# 测试聚合函数
|
||||
agg_result = df.groupby('A').agg({'B': 'sum'})
|
||||
print("✅ groupby聚合函数正常")
|
||||
|
||||
# 测试Excel读写
|
||||
test_file = Path('test_pandas.xlsx')
|
||||
df.to_excel(test_file, index=False)
|
||||
df_read = pd.read_excel(test_file)
|
||||
test_file.unlink() # 删除测试文件
|
||||
print("✅ Excel读写功能正常")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ pandas功能测试失败: {e}")
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def check_pandas_installation():
|
||||
"""检查pandas安装信息"""
|
||||
print("\n" + "=" * 50)
|
||||
print("pandas安装信息")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
import pandas as pd
|
||||
print(f"✅ pandas版本: {pd.__version__}")
|
||||
print(f"✅ pandas路径: {pd.__file__}")
|
||||
|
||||
# 检查_libs目录
|
||||
pandas_path = Path(pd.__file__).parent
|
||||
libs_path = pandas_path / '_libs'
|
||||
|
||||
if libs_path.exists():
|
||||
print(f"✅ _libs目录存在: {libs_path}")
|
||||
|
||||
# 统计.pyd文件
|
||||
pyd_files = list(libs_path.glob('**/*.pyd'))
|
||||
print(f"✅ 找到 {len(pyd_files)} 个.pyd文件")
|
||||
|
||||
# 检查关键文件
|
||||
key_files = [
|
||||
'window/aggregations.cp310-win_amd64.pyd',
|
||||
'window/indexers.cp310-win_amd64.pyd',
|
||||
'hashtable.cp310-win_amd64.pyd',
|
||||
'lib.cp310-win_amd64.pyd'
|
||||
]
|
||||
|
||||
for key_file in key_files:
|
||||
file_path = libs_path / key_file
|
||||
if file_path.exists():
|
||||
print(f"✅ 关键文件存在: {key_file}")
|
||||
else:
|
||||
print(f"❌ 关键文件缺失: {key_file}")
|
||||
else:
|
||||
print(f"❌ _libs目录不存在: {libs_path}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 检查pandas安装失败: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("🔍 pandas DLL模块测试工具")
|
||||
print("用于诊断PyInstaller构建问题")
|
||||
print()
|
||||
|
||||
# 基本信息
|
||||
print(f"Python版本: {sys.version}")
|
||||
print(f"平台: {sys.platform}")
|
||||
|
||||
# 运行测试
|
||||
install_ok = check_pandas_installation()
|
||||
core_ok = test_pandas_core()
|
||||
func_ok = test_pandas_functionality()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("测试结果总结")
|
||||
print("=" * 50)
|
||||
|
||||
if install_ok and core_ok and func_ok:
|
||||
print("✅ 所有测试通过!pandas安装正常")
|
||||
print("💡 如果PyInstaller仍有问题,请使用 fix_dll_build.py")
|
||||
else:
|
||||
print("❌ 存在问题,建议:")
|
||||
if not install_ok:
|
||||
print(" 1. 重新安装pandas: pip uninstall pandas && pip install pandas")
|
||||
if not core_ok:
|
||||
print(" 2. 检查pandas C扩展是否正确编译")
|
||||
if not func_ok:
|
||||
print(" 3. 检查依赖库(numpy等)是否正常")
|
||||
|
||||
print("=" * 50)
|
||||
input("\n按Enter键退出...")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user