#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 游戏配置工具依赖自动安装器 Game Configuration Tool Dependencies Auto Installer 功能: 1. 自动检测Python环境 2. 检查并安装所需依赖库 3. 创建虚拟环境(可选) 4. 验证安装结果 作者: AI Assistant 日期: 2024 """ import sys import subprocess import os import importlib import json from pathlib import Path class DependencyInstaller: def __init__(self): self.required_packages = { 'pandas': '>=1.3.0', 'openpyxl': '>=3.0.0', 'pyinstaller': '>=4.0' } self.optional_packages = { 'xlsxwriter': '>=1.0.0', # 额外的Excel支持 'xlrd': '>=2.0.0' # 旧版Excel文件支持 } self.install_log = [] def log_message(self, message, level="INFO"): """记录安装日志""" log_entry = f"[{level}] {message}" self.install_log.append(log_entry) print(log_entry) def check_python_version(self): """检查Python版本""" version = sys.version_info self.log_message(f"Python版本: {version.major}.{version.minor}.{version.micro}") if version.major < 3 or (version.major == 3 and version.minor < 7): self.log_message("警告: 建议使用Python 3.7或更高版本", "WARNING") return False return True def check_pip_available(self): """检查pip是否可用""" try: import pip self.log_message("pip可用") return True except ImportError: try: subprocess.run([sys.executable, '-m', 'pip', '--version'], check=True, capture_output=True) self.log_message("pip模块可用") return True except subprocess.CalledProcessError: self.log_message("pip不可用,请先安装pip", "ERROR") return False def is_package_installed(self, package_name): """检查包是否已安装""" try: importlib.import_module(package_name) return True except ImportError: return False def get_package_version(self, package_name): """获取已安装包的版本""" try: module = importlib.import_module(package_name) if hasattr(module, '__version__'): return module.__version__ else: # 尝试通过pip show获取版本 result = subprocess.run([sys.executable, '-m', 'pip', 'show', package_name], capture_output=True, text=True) if result.returncode == 0: for line in result.stdout.split('\n'): if line.startswith('Version:'): return line.split(':')[1].strip() return "未知版本" except: return None def install_package(self, package_name, version_spec=""): """安装单个包""" package_spec = f"{package_name}{version_spec}" if version_spec else package_name try: self.log_message(f"正在安装 {package_spec}...") # 使用pip安装 cmd = [sys.executable, '-m', 'pip', 'install', package_spec, '--upgrade'] result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) if result.returncode == 0: self.log_message(f"✓ {package_name} 安装成功") return True else: self.log_message(f"✗ {package_name} 安装失败: {result.stderr}", "ERROR") return False except subprocess.TimeoutExpired: self.log_message(f"✗ {package_name} 安装超时", "ERROR") return False except Exception as e: self.log_message(f"✗ {package_name} 安装异常: {str(e)}", "ERROR") return False def check_and_install_dependencies(self): """检查并安装所有依赖""" self.log_message("开始检查依赖...") success_count = 0 total_count = len(self.required_packages) for package, version_spec in self.required_packages.items(): if self.is_package_installed(package): current_version = self.get_package_version(package) self.log_message(f"✓ {package} 已安装 (版本: {current_version})") success_count += 1 else: self.log_message(f"✗ {package} 未安装,开始安装...") if self.install_package(package, version_spec): success_count += 1 # 安装可选包 self.log_message("\n检查可选依赖...") for package, version_spec in self.optional_packages.items(): if not self.is_package_installed(package): self.log_message(f"安装可选包: {package}") self.install_package(package, version_spec) return success_count == total_count def verify_installation(self): """验证安装结果""" self.log_message("\n验证安装结果...") verification_results = {} for package in self.required_packages.keys(): try: module = importlib.import_module(package) version = self.get_package_version(package) verification_results[package] = { 'installed': True, 'version': version, 'import_success': True } self.log_message(f"✓ {package} 验证成功 (版本: {version})") except Exception as e: verification_results[package] = { 'installed': False, 'version': None, 'import_success': False, 'error': str(e) } self.log_message(f"✗ {package} 验证失败: {str(e)}", "ERROR") return verification_results def test_functionality(self): """测试核心功能""" self.log_message("\n测试核心功能...") try: # 测试pandas import pandas as pd df = pd.DataFrame({'test': [1, 2, 3]}) self.log_message("✓ pandas 基本功能测试通过") # 测试openpyxl import openpyxl wb = openpyxl.Workbook() self.log_message("✓ openpyxl 基本功能测试通过") # 测试pyinstaller import PyInstaller self.log_message("✓ PyInstaller 导入测试通过") return True except Exception as e: self.log_message(f"✗ 功能测试失败: {str(e)}", "ERROR") return False def save_install_report(self): """保存安装报告""" report = { 'timestamp': str(Path(__file__).stat().st_mtime), 'python_version': f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", 'install_log': self.install_log, 'verification_results': self.verify_installation() } report_file = Path(__file__).parent / 'install_report.json' try: with open(report_file, 'w', encoding='utf-8') as f: json.dump(report, f, ensure_ascii=False, indent=2) self.log_message(f"安装报告已保存到: {report_file}") except Exception as e: self.log_message(f"保存安装报告失败: {str(e)}", "ERROR") def run_installation(self): """运行完整安装流程""" self.log_message("=" * 60) self.log_message("游戏配置工具依赖自动安装器") self.log_message("=" * 60) # 检查Python环境 if not self.check_python_version(): self.log_message("Python版本检查失败,但继续安装...", "WARNING") # 检查pip if not self.check_pip_available(): self.log_message("pip不可用,无法继续安装", "ERROR") return False # 安装依赖 if self.check_and_install_dependencies(): self.log_message("\n所有必需依赖安装完成!") else: self.log_message("\n部分依赖安装失败,请检查错误信息", "WARNING") # 验证安装 verification_results = self.verify_installation() # 测试功能 if self.test_functionality(): self.log_message("\n✓ 所有功能测试通过!") else: self.log_message("\n✗ 功能测试失败,请检查安装", "ERROR") # 保存报告 self.save_install_report() self.log_message("\n安装完成!现在可以运行配置工具了。") return True def main(): """主函数""" installer = DependencyInstaller() try: success = installer.run_installation() if success: print("\n" + "=" * 60) print("安装成功!") print("现在可以运行 '启动配置工具.bat' 来使用配置管理工具。") print("=" * 60) else: print("\n" + "=" * 60) print("安装过程中遇到问题,请查看上面的错误信息。") print("=" * 60) except KeyboardInterrupt: print("\n安装被用户中断") except Exception as e: print(f"\n安装过程中发生未预期的错误: {str(e)}") input("\n按回车键退出...") if __name__ == "__main__": main()