|
|
@@ -0,0 +1,279 @@
|
|
|
+#!/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()
|