install_dependencies.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 游戏配置工具依赖自动安装器
  5. Game Configuration Tool Dependencies Auto Installer
  6. 功能:
  7. 1. 自动检测Python环境
  8. 2. 检查并安装所需依赖库
  9. 3. 创建虚拟环境(可选)
  10. 4. 验证安装结果
  11. 作者: AI Assistant
  12. 日期: 2024
  13. """
  14. import sys
  15. import subprocess
  16. import os
  17. import importlib
  18. import json
  19. from pathlib import Path
  20. class DependencyInstaller:
  21. def __init__(self):
  22. self.required_packages = {
  23. 'pandas': '>=1.3.0',
  24. 'openpyxl': '>=3.0.0',
  25. 'pyinstaller': '>=4.0'
  26. }
  27. self.optional_packages = {
  28. 'xlsxwriter': '>=1.0.0', # 额外的Excel支持
  29. 'xlrd': '>=2.0.0' # 旧版Excel文件支持
  30. }
  31. self.install_log = []
  32. def log_message(self, message, level="INFO"):
  33. """记录安装日志"""
  34. log_entry = f"[{level}] {message}"
  35. self.install_log.append(log_entry)
  36. print(log_entry)
  37. def check_python_version(self):
  38. """检查Python版本"""
  39. version = sys.version_info
  40. self.log_message(f"Python版本: {version.major}.{version.minor}.{version.micro}")
  41. if version.major < 3 or (version.major == 3 and version.minor < 7):
  42. self.log_message("警告: 建议使用Python 3.7或更高版本", "WARNING")
  43. return False
  44. return True
  45. def check_pip_available(self):
  46. """检查pip是否可用"""
  47. try:
  48. import pip
  49. self.log_message("pip可用")
  50. return True
  51. except ImportError:
  52. try:
  53. subprocess.run([sys.executable, '-m', 'pip', '--version'],
  54. check=True, capture_output=True)
  55. self.log_message("pip模块可用")
  56. return True
  57. except subprocess.CalledProcessError:
  58. self.log_message("pip不可用,请先安装pip", "ERROR")
  59. return False
  60. def is_package_installed(self, package_name):
  61. """检查包是否已安装"""
  62. try:
  63. importlib.import_module(package_name)
  64. return True
  65. except ImportError:
  66. return False
  67. def get_package_version(self, package_name):
  68. """获取已安装包的版本"""
  69. try:
  70. module = importlib.import_module(package_name)
  71. if hasattr(module, '__version__'):
  72. return module.__version__
  73. else:
  74. # 尝试通过pip show获取版本
  75. result = subprocess.run([sys.executable, '-m', 'pip', 'show', package_name],
  76. capture_output=True, text=True)
  77. if result.returncode == 0:
  78. for line in result.stdout.split('\n'):
  79. if line.startswith('Version:'):
  80. return line.split(':')[1].strip()
  81. return "未知版本"
  82. except:
  83. return None
  84. def install_package(self, package_name, version_spec=""):
  85. """安装单个包"""
  86. package_spec = f"{package_name}{version_spec}" if version_spec else package_name
  87. try:
  88. self.log_message(f"正在安装 {package_spec}...")
  89. # 使用pip安装
  90. cmd = [sys.executable, '-m', 'pip', 'install', package_spec, '--upgrade']
  91. result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
  92. if result.returncode == 0:
  93. self.log_message(f"✓ {package_name} 安装成功")
  94. return True
  95. else:
  96. self.log_message(f"✗ {package_name} 安装失败: {result.stderr}", "ERROR")
  97. return False
  98. except subprocess.TimeoutExpired:
  99. self.log_message(f"✗ {package_name} 安装超时", "ERROR")
  100. return False
  101. except Exception as e:
  102. self.log_message(f"✗ {package_name} 安装异常: {str(e)}", "ERROR")
  103. return False
  104. def check_and_install_dependencies(self):
  105. """检查并安装所有依赖"""
  106. self.log_message("开始检查依赖...")
  107. success_count = 0
  108. total_count = len(self.required_packages)
  109. for package, version_spec in self.required_packages.items():
  110. if self.is_package_installed(package):
  111. current_version = self.get_package_version(package)
  112. self.log_message(f"✓ {package} 已安装 (版本: {current_version})")
  113. success_count += 1
  114. else:
  115. self.log_message(f"✗ {package} 未安装,开始安装...")
  116. if self.install_package(package, version_spec):
  117. success_count += 1
  118. # 安装可选包
  119. self.log_message("\n检查可选依赖...")
  120. for package, version_spec in self.optional_packages.items():
  121. if not self.is_package_installed(package):
  122. self.log_message(f"安装可选包: {package}")
  123. self.install_package(package, version_spec)
  124. return success_count == total_count
  125. def verify_installation(self):
  126. """验证安装结果"""
  127. self.log_message("\n验证安装结果...")
  128. verification_results = {}
  129. for package in self.required_packages.keys():
  130. try:
  131. module = importlib.import_module(package)
  132. version = self.get_package_version(package)
  133. verification_results[package] = {
  134. 'installed': True,
  135. 'version': version,
  136. 'import_success': True
  137. }
  138. self.log_message(f"✓ {package} 验证成功 (版本: {version})")
  139. except Exception as e:
  140. verification_results[package] = {
  141. 'installed': False,
  142. 'version': None,
  143. 'import_success': False,
  144. 'error': str(e)
  145. }
  146. self.log_message(f"✗ {package} 验证失败: {str(e)}", "ERROR")
  147. return verification_results
  148. def test_functionality(self):
  149. """测试核心功能"""
  150. self.log_message("\n测试核心功能...")
  151. try:
  152. # 测试pandas
  153. import pandas as pd
  154. df = pd.DataFrame({'test': [1, 2, 3]})
  155. self.log_message("✓ pandas 基本功能测试通过")
  156. # 测试openpyxl
  157. import openpyxl
  158. wb = openpyxl.Workbook()
  159. self.log_message("✓ openpyxl 基本功能测试通过")
  160. # 测试pyinstaller
  161. import PyInstaller
  162. self.log_message("✓ PyInstaller 导入测试通过")
  163. return True
  164. except Exception as e:
  165. self.log_message(f"✗ 功能测试失败: {str(e)}", "ERROR")
  166. return False
  167. def save_install_report(self):
  168. """保存安装报告"""
  169. report = {
  170. 'timestamp': str(Path(__file__).stat().st_mtime),
  171. 'python_version': f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
  172. 'install_log': self.install_log,
  173. 'verification_results': self.verify_installation()
  174. }
  175. report_file = Path(__file__).parent / 'install_report.json'
  176. try:
  177. with open(report_file, 'w', encoding='utf-8') as f:
  178. json.dump(report, f, ensure_ascii=False, indent=2)
  179. self.log_message(f"安装报告已保存到: {report_file}")
  180. except Exception as e:
  181. self.log_message(f"保存安装报告失败: {str(e)}", "ERROR")
  182. def run_installation(self):
  183. """运行完整安装流程"""
  184. self.log_message("=" * 60)
  185. self.log_message("游戏配置工具依赖自动安装器")
  186. self.log_message("=" * 60)
  187. # 检查Python环境
  188. if not self.check_python_version():
  189. self.log_message("Python版本检查失败,但继续安装...", "WARNING")
  190. # 检查pip
  191. if not self.check_pip_available():
  192. self.log_message("pip不可用,无法继续安装", "ERROR")
  193. return False
  194. # 安装依赖
  195. if self.check_and_install_dependencies():
  196. self.log_message("\n所有必需依赖安装完成!")
  197. else:
  198. self.log_message("\n部分依赖安装失败,请检查错误信息", "WARNING")
  199. # 验证安装
  200. verification_results = self.verify_installation()
  201. # 测试功能
  202. if self.test_functionality():
  203. self.log_message("\n✓ 所有功能测试通过!")
  204. else:
  205. self.log_message("\n✗ 功能测试失败,请检查安装", "ERROR")
  206. # 保存报告
  207. self.save_install_report()
  208. self.log_message("\n安装完成!现在可以运行配置工具了。")
  209. return True
  210. def main():
  211. """主函数"""
  212. installer = DependencyInstaller()
  213. try:
  214. success = installer.run_installation()
  215. if success:
  216. print("\n" + "=" * 60)
  217. print("安装成功!")
  218. print("现在可以运行 '启动配置工具.bat' 来使用配置管理工具。")
  219. print("=" * 60)
  220. else:
  221. print("\n" + "=" * 60)
  222. print("安装过程中遇到问题,请查看上面的错误信息。")
  223. print("=" * 60)
  224. except KeyboardInterrupt:
  225. print("\n安装被用户中断")
  226. except Exception as e:
  227. print(f"\n安装过程中发生未预期的错误: {str(e)}")
  228. input("\n按回车键退出...")
  229. if __name__ == "__main__":
  230. main()