from module_bank import PythonToSQLite import os from pathlib import Path import shutil import subprocess import sys def run_pyinstaller(): """运行 PyInstaller 打包成可执行文件""" try: # 构建 PyInstaller 命令 cmd = [ sys.executable, "-m", "PyInstaller", "--onefile", "--name", "chongming", "--distpath", ".", "--workpath", "./build_temp", "--specpath", "./specs", "--clean", # 隐藏导入 "--hidden-import", "passlib", "--hidden-import", "passlib.context", "--hidden-import", "passlib.handlers.bcrypt", "--hidden-import", "fastapi", "--hidden-import", "fastapi.middleware.cors", "--hidden-import", "pydantic_settings", "--hidden-import", "tortoise", "--hidden-import", "tortoise.contrib.fastapi", "--hidden-import", "aerich", "--hidden-import", "uvicorn", "--hidden-import", "application", # 复制包元数据 - 解决 importlib.metadata 问题 "--copy-metadata", "tortoise-orm", "--copy-metadata", "aerich", "--copy-metadata", "fastapi", "--copy-metadata", "uvicorn", "--copy-metadata", "pydantic", "--copy-metadata", "pydantic-settings", "--copy-metadata", "module-bank", "--copy-metadata", "passlib", "--copy-metadata", "sqlite-vfs", "--copy-metadata", "toml", # 收集整个包 "--collect-all", "tortoise-orm", "--collect-all", "aerich", # 禁用多进程优化 # "--multiprocessing-fork", # 明确指定使用 fork 模式 # 添加数据文件 # "--add-data", "resources:resources", # 其他选项 "--icon", "../resources/chongming.ico", "./main.py" ] print(f"正在运行 PyInstaller: {' '.join(cmd)}") result = subprocess.run(cmd, cwd="./build", capture_output=True, text=True) if result.returncode == 0: print("PyInstaller 打包成功!") print(result.stdout) else: print("PyInstaller 打包失败!") print("错误信息:", result.stderr) except FileNotFoundError: print("错误:未找到 PyInstaller,请先安装 PyInstaller:pip install pyinstaller") except Exception as e: print(f"PyInstaller 执行出错: {e}") def main(): # 打包模块 app_packer = PythonToSQLite("./resources/app.mbank") app_packer.pack_directory("app/") app_packer.verify_package_structure() app_packer.delete_source_code(None) plugin_packer = PythonToSQLite("./resources/plugins.mbank") plugin_packer.pack_directory("plugins/") plugin_packer.verify_package_structure() plugin_packer.delete_source_code(None) # 创建 build 目录 build_path = Path("build") if build_path.exists() and build_path.is_dir(): shutil.rmtree("build") os.makedirs("build", exist_ok=True) # 复制 utils 文件夹到 build 文件夹 utils_path = Path("utils") if utils_path.exists(): target_utils_path = Path("build") / "utils" shutil.copytree(utils_path, target_utils_path, dirs_exist_ok=True) print(f"已复制 utils 文件夹到 {target_utils_path}") # 复制 resources 文件夹到 build 文件夹 resources_path = Path("resources") if resources_path.exists(): target_resources_path = Path("build") / "resources" shutil.copytree(resources_path, target_resources_path, dirs_exist_ok=True) print(f"已复制 resources 文件夹到 {target_resources_path}") print("模块打包完成") # 复制 main.py 到 build 文件夹 shutil.copy("main.py", "build") # 复制 config.toml 到 build 文件夹 shutil.copy("config.toml", "build") # 运行 PyInstaller run_pyinstaller() # 清理临时文件 shutil.rmtree(r"build/build_temp", ignore_errors=True) shutil.rmtree(r"build/specs", ignore_errors=True) shutil.rmtree(r"build/utils", ignore_errors=True) os.remove(r"build/main.py") # os.remove(r"build/config.toml") print("构建完成") if __name__ == "__main__": main()