import os import sys import shutil import subprocess import platform import datetime import argparse import time import traceback def check_pyinstaller(): """检查是否已安装 PyInstaller,如果没有则安装""" try: subprocess.run(["pyinstaller", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) print("✅ PyInstaller 已安装") return True except (subprocess.SubprocessError, FileNotFoundError): print("❌ PyInstaller 未安装,正在安装...") try: subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True) print("✅ PyInstaller 安装成功") return True except subprocess.SubprocessError as e: print(f"❌ PyInstaller 安装失败: {e}") return False def create_executable(app_name, keep_previous): """使用 PyInstaller 创建可执行文件""" print(f"开始打包 cursor_pro_register.py 为 {app_name}...") dist_folder = "dist" build_folder = "build" # 如果不保留旧版本,则清除dist和build目录 if not keep_previous: for folder in [dist_folder, build_folder]: if os.path.exists(folder): shutil.rmtree(folder) print(f"已清理 {folder} 文件夹") else: # 确保目录存在 os.makedirs(dist_folder, exist_ok=True) os.makedirs(build_folder, exist_ok=True) print("将保留先前版本") # 生成版本标识(用于区分构建文件夹) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") build_dir = os.path.join(build_folder, f"build_{timestamp}") # 检查是否存在 spec 文件并删除 if os.path.exists("cursor_pro_register.spec"): os.remove("cursor_pro_register.spec") print("已删除旧的 spec 文件") # 确定输出文件名 output_name = app_name if app_name else "cursor动态账号注册机" print(f"输出文件名设置为: {output_name}") # 构建命令 cmd = [ "pyinstaller", "--onefile", # 创建单个可执行文件 "--name", output_name, "--clean", # 清理临时文件 "--workpath", build_dir, # 使用唯一的构建目录 # 移除noconsole选项,使用控制台模式 "--noupx", # 不使用UPX压缩,提高兼容性 "--add-data", f"turnstilePatch{os.pathsep}turnstilePatch", # 添加额外文件 "cursor_pro_register.py" ] # 过滤空字符串 cmd = [item for item in cmd if item] print(f"执行命令: {' '.join(cmd)}") try: # 运行 PyInstaller subprocess.run(cmd, check=True) executable_name = f"{output_name}.exe" if platform.system() == "Windows" else output_name executable_path = os.path.join("dist", executable_name) if os.path.exists(executable_path): print(f"\n✅ 打包成功! 可执行文件位于: {executable_path}") # 获取文件大小 size_bytes = os.path.getsize(executable_path) size_mb = size_bytes / (1024 * 1024) print(f"可执行文件大小: {size_mb:.2f} MB") return True else: print(f"❌ 打包过程可能出错,找不到可执行文件: {executable_path}") return False except subprocess.SubprocessError as e: print(f"❌ 打包失败: {e}") traceback.print_exc() # 打印详细的错误信息 return False if __name__ == "__main__": print("=" * 50) print("Cursor Pro Register 打包工具") print("=" * 50) # 解析命令行参数 parser = argparse.ArgumentParser(description="Cursor Pro Register 打包工具") parser.add_argument("app_name", nargs="?", default="cursor动态账号注册机", help="应用名称") parser.add_argument("keep_previous", nargs="?", type=int, default=0, help="是否保留先前版本 (1=是, 0=否)") try: args = parser.parse_args() print(f"接收到的参数: 应用名称=\"{args.app_name}\", 保留旧版本={bool(args.keep_previous)}") # 检查当前目录是否有 cursor_pro_register.py if not os.path.exists("cursor_pro_register.py"): print("❌ 当前目录找不到 cursor_pro_register.py 文件!") sys.exit(1) # 检查是否有 turnstilePatch 目录 if not os.path.exists("turnstilePatch"): print("⚠️ 警告: 找不到 turnstilePatch 目录,打包可能会缺少必要文件") try: choice = input("是否继续打包? (y/n): ") if choice.lower() != 'y': print("打包已取消") sys.exit(0) except Exception: # 如果input()出错,默认继续 print("⚠️ 无法获取用户输入,默认继续打包...") # 检查并安装 PyInstaller if not check_pyinstaller(): print("❌ 无法安装 PyInstaller,打包终止") sys.exit(1) # 创建可执行文件 if create_executable(args.app_name, bool(args.keep_previous)): print("\n打包过程完成!") else: print("\n打包过程出现错误,请检查上面的日志信息") except Exception as e: print(f"❌ 执行过程中出现未预期的错误: {e}") traceback.print_exc() print("程序将在5秒后自动退出...") time.sleep(5)