build_installer.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 依赖安装器构建脚本
  5. Build script for dependency installer
  6. 功能:
  7. 1. 使用PyInstaller将install_dependencies.py打包成exe
  8. 2. 创建便携式安装包
  9. 3. 生成安装说明文档
  10. 作者: AI Assistant
  11. 日期: 2024
  12. """
  13. import os
  14. import sys
  15. import subprocess
  16. import shutil
  17. from pathlib import Path
  18. import json
  19. class InstallerBuilder:
  20. def __init__(self):
  21. self.script_dir = Path(__file__).parent
  22. self.build_dir = self.script_dir / "build"
  23. self.dist_dir = self.script_dir / "dist"
  24. self.installer_dir = self.script_dir / "installer_package"
  25. def check_pyinstaller(self):
  26. """检查PyInstaller是否可用"""
  27. try:
  28. import PyInstaller
  29. print("✓ PyInstaller 已安装")
  30. return True
  31. except ImportError:
  32. print("✗ PyInstaller 未安装,正在安装...")
  33. try:
  34. subprocess.run([sys.executable, '-m', 'pip', 'install', 'pyinstaller'],
  35. check=True)
  36. print("✓ PyInstaller 安装成功")
  37. return True
  38. except subprocess.CalledProcessError:
  39. print("✗ PyInstaller 安装失败")
  40. return False
  41. def create_spec_file(self):
  42. """创建PyInstaller规格文件"""
  43. spec_content = '''# -*- mode: python ; coding: utf-8 -*-
  44. block_cipher = None
  45. a = Analysis(
  46. ['install_dependencies.py'],
  47. pathex=[],
  48. binaries=[],
  49. datas=[
  50. ('requirements.txt', '.'),
  51. ],
  52. hiddenimports=[
  53. 'pkg_resources.py2_warn',
  54. 'packaging',
  55. 'packaging.version',
  56. 'packaging.specifiers',
  57. 'packaging.requirements',
  58. ],
  59. hookspath=[],
  60. hooksconfig={},
  61. runtime_hooks=[],
  62. excludes=[],
  63. win_no_prefer_redirects=False,
  64. win_private_assemblies=False,
  65. cipher=block_cipher,
  66. noarchive=False,
  67. )
  68. pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
  69. exe = EXE(
  70. pyz,
  71. a.scripts,
  72. a.binaries,
  73. a.zipfiles,
  74. a.datas,
  75. [],
  76. name='游戏配置工具依赖安装器',
  77. debug=False,
  78. bootloader_ignore_signals=False,
  79. strip=False,
  80. upx=True,
  81. upx_exclude=[],
  82. runtime_tmpdir=None,
  83. console=True,
  84. disable_windowed_traceback=False,
  85. argv_emulation=False,
  86. target_arch=None,
  87. codesign_identity=None,
  88. entitlements_file=None,
  89. icon=None,
  90. )
  91. '''
  92. spec_file = self.script_dir / "installer.spec"
  93. with open(spec_file, 'w', encoding='utf-8') as f:
  94. f.write(spec_content)
  95. print(f"✓ 规格文件已创建: {spec_file}")
  96. return spec_file
  97. def build_executable(self):
  98. """构建可执行文件"""
  99. spec_file = self.create_spec_file()
  100. try:
  101. print("开始构建可执行文件...")
  102. cmd = [
  103. sys.executable, '-m', 'PyInstaller',
  104. '--clean',
  105. '--noconfirm',
  106. str(spec_file)
  107. ]
  108. result = subprocess.run(cmd, cwd=self.script_dir, capture_output=True, text=True)
  109. if result.returncode == 0:
  110. print("✓ 可执行文件构建成功")
  111. return True
  112. else:
  113. print(f"✗ 构建失败: {result.stderr}")
  114. return False
  115. except Exception as e:
  116. print(f"✗ 构建过程中发生错误: {str(e)}")
  117. return False
  118. def create_installer_package(self):
  119. """创建安装包目录"""
  120. # 清理并创建安装包目录
  121. if self.installer_dir.exists():
  122. shutil.rmtree(self.installer_dir)
  123. self.installer_dir.mkdir()
  124. # 复制可执行文件
  125. exe_source = self.dist_dir / "游戏配置工具依赖安装器.exe"
  126. exe_dest = self.installer_dir / "游戏配置工具依赖安装器.exe"
  127. if exe_source.exists():
  128. shutil.copy2(exe_source, exe_dest)
  129. print(f"✓ 可执行文件已复制到: {exe_dest}")
  130. else:
  131. print(f"✗ 找不到可执行文件: {exe_source}")
  132. return False
  133. # 复制相关文件
  134. files_to_copy = [
  135. 'requirements.txt',
  136. '启动配置工具.bat'
  137. ]
  138. for file_name in files_to_copy:
  139. source = self.script_dir / file_name
  140. if source.exists():
  141. dest = self.installer_dir / file_name
  142. shutil.copy2(source, dest)
  143. print(f"✓ 已复制: {file_name}")
  144. return True
  145. def create_readme(self):
  146. """创建使用说明文档"""
  147. readme_content = '''# 游戏配置工具依赖安装器
  148. ## 简介
  149. 这是一个自动安装游戏配置管理工具所需Python依赖库的工具。
  150. ## 使用方法
  151. ### 方法一:使用可执行文件(推荐)
  152. 1. 双击运行 `游戏配置工具依赖安装器.exe`
  153. 2. 等待安装完成
  154. 3. 运行 `启动配置工具.bat` 使用配置管理工具
  155. ### 方法二:使用Python脚本
  156. 如果可执行文件无法运行,可以直接使用Python脚本:
  157. 1. 确保已安装Python 3.7或更高版本
  158. 2. 运行命令:`python install_dependencies.py`
  159. ## 安装的依赖库
  160. - **pandas**: Excel和CSV文件处理
  161. - **openpyxl**: Excel文件读写支持
  162. - **pyinstaller**: 用于打包Python脚本(可选)
  163. - **xlsxwriter**: 额外的Excel支持(可选)
  164. - **xlrd**: 旧版Excel文件支持(可选)
  165. ## 系统要求
  166. - Windows 7/8/10/11
  167. - Python 3.7+ (如果使用Python脚本)
  168. - 网络连接(用于下载依赖库)
  169. ## 故障排除
  170. ### 问题1:可执行文件无法运行
  171. - 确保Windows Defender或杀毒软件没有阻止程序运行
  172. - 尝试以管理员身份运行
  173. - 使用Python脚本方式安装
  174. ### 问题2:网络连接问题
  175. - 检查网络连接
  176. - 如果在公司网络环境,可能需要配置代理
  177. - 可以尝试使用手机热点
  178. ### 问题3:权限问题
  179. - 以管理员身份运行安装器
  180. - 确保对Python安装目录有写入权限
  181. ### 问题4:Python版本问题
  182. - 确保使用Python 3.7或更高版本
  183. - 可以从 https://python.org 下载最新版本
  184. ## 验证安装
  185. 安装完成后,会生成 `install_report.json` 文件,包含详细的安装信息。
  186. ## 联系支持
  187. 如果遇到问题,请检查:
  188. 1. `install_report.json` 文件中的错误信息
  189. 2. 确保网络连接正常
  190. 3. 确保Python环境正确配置
  191. ---
  192. 生成时间: {timestamp}
  193. 版本: 1.0.0
  194. '''
  195. from datetime import datetime
  196. readme_content = readme_content.format(
  197. timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  198. )
  199. readme_file = self.installer_dir / "README.md"
  200. with open(readme_file, 'w', encoding='utf-8') as f:
  201. f.write(readme_content)
  202. print(f"✓ 使用说明已创建: {readme_file}")
  203. def create_batch_installer(self):
  204. """创建批处理安装脚本"""
  205. batch_content = '''@echo off
  206. chcp 65001 >nul
  207. echo ========================================
  208. echo 游戏配置工具依赖自动安装器
  209. echo ========================================
  210. echo.
  211. echo 正在检查Python环境...
  212. python --version >nul 2>&1
  213. if errorlevel 1 (
  214. echo 错误: 未找到Python环境
  215. echo 请先安装Python 3.7或更高版本
  216. echo 下载地址: https://python.org
  217. echo.
  218. pause
  219. exit /b 1
  220. )
  221. echo Python环境检查通过
  222. echo.
  223. echo 开始安装依赖库...
  224. "游戏配置工具依赖安装器.exe"
  225. echo.
  226. echo 安装完成!
  227. echo 现在可以运行 "启动配置工具.bat" 来使用配置管理工具
  228. echo.
  229. pause
  230. '''
  231. batch_file = self.installer_dir / "一键安装依赖.bat"
  232. with open(batch_file, 'w', encoding='gbk') as f:
  233. f.write(batch_content)
  234. print(f"✓ 批处理安装脚本已创建: {batch_file}")
  235. def cleanup_build_files(self):
  236. """清理构建文件"""
  237. try:
  238. if self.build_dir.exists():
  239. shutil.rmtree(self.build_dir)
  240. print("✓ 构建临时文件已清理")
  241. # 保留dist目录,但可以选择清理
  242. # if self.dist_dir.exists():
  243. # shutil.rmtree(self.dist_dir)
  244. spec_file = self.script_dir / "installer.spec"
  245. if spec_file.exists():
  246. spec_file.unlink()
  247. print("✓ 规格文件已清理")
  248. except Exception as e:
  249. print(f"清理文件时发生错误: {str(e)}")
  250. def build_complete_installer(self):
  251. """构建完整的安装包"""
  252. print("=" * 60)
  253. print("游戏配置工具依赖安装器构建脚本")
  254. print("=" * 60)
  255. # 检查PyInstaller
  256. if not self.check_pyinstaller():
  257. return False
  258. # 构建可执行文件
  259. if not self.build_executable():
  260. return False
  261. # 创建安装包
  262. if not self.create_installer_package():
  263. return False
  264. # 创建文档
  265. self.create_readme()
  266. self.create_batch_installer()
  267. # 清理构建文件
  268. self.cleanup_build_files()
  269. print("\n" + "=" * 60)
  270. print("构建完成!")
  271. print(f"安装包位置: {self.installer_dir}")
  272. print("=" * 60)
  273. print("\n安装包内容:")
  274. for item in self.installer_dir.iterdir():
  275. print(f" - {item.name}")
  276. return True
  277. def main():
  278. """主函数"""
  279. builder = InstallerBuilder()
  280. try:
  281. success = builder.build_complete_installer()
  282. if success:
  283. print("\n构建成功!")
  284. print("现在可以将 'installer_package' 目录复制到其他电脑使用。")
  285. else:
  286. print("\n构建失败,请检查错误信息。")
  287. except KeyboardInterrupt:
  288. print("\n构建被用户中断")
  289. except Exception as e:
  290. print(f"\n构建过程中发生未预期的错误: {str(e)}")
  291. input("\n按回车键退出...")
  292. if __name__ == "__main__":
  293. main()