first commit
This commit is contained in:
223
package_spec.py
Normal file
223
package_spec.py
Normal file
@@ -0,0 +1,223 @@
|
||||
"""
|
||||
更高级的打包脚本,使用 spec 文件进行更精细的控制
|
||||
这个脚本会生成一个 .spec 文件并基于它进行打包
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import subprocess
|
||||
import platform
|
||||
import datetime
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
def install_requirements():
|
||||
"""安装必要的依赖"""
|
||||
requirements = ["pyinstaller", "colorama", "requests"]
|
||||
|
||||
for req in requirements:
|
||||
print(f"正在检查 {req}...")
|
||||
try:
|
||||
__import__(req)
|
||||
print(f"✅ {req} 已安装")
|
||||
except ImportError:
|
||||
print(f"❌ {req} 未安装,正在安装...")
|
||||
try:
|
||||
subprocess.run([sys.executable, "-m", "pip", "install", req], check=True)
|
||||
print(f"✅ {req} 安装成功")
|
||||
except subprocess.SubprocessError as e:
|
||||
print(f"❌ {req} 安装失败: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def create_spec_file(app_name):
|
||||
"""创建 .spec 文件"""
|
||||
print("正在创建 .spec 文件...")
|
||||
|
||||
# 获取当前工作目录
|
||||
current_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
# 自动检测项目中的所有 Python 文件
|
||||
python_files = []
|
||||
for file in os.listdir(current_dir):
|
||||
if file.endswith('.py') and file != 'package.py' and file != 'package_spec.py':
|
||||
python_files.append(file)
|
||||
|
||||
main_script = 'cursor_pro_register.py'
|
||||
if main_script not in python_files:
|
||||
print(f"❌ 找不到主脚本文件 {main_script}!")
|
||||
return False
|
||||
|
||||
# 确保 turnstilePatch 目录存在
|
||||
turnstile_path = os.path.join(current_dir, 'turnstilePatch')
|
||||
if not os.path.exists(turnstile_path):
|
||||
print("⚠️ 警告: 找不到 turnstilePatch 目录,功能可能受限")
|
||||
|
||||
# 获取资源文件
|
||||
datas = []
|
||||
if os.path.exists(turnstile_path):
|
||||
datas.append((turnstile_path, 'turnstilePatch'))
|
||||
|
||||
# 检查其他可能的资源文件夹
|
||||
for folder in ['assets', 'config', 'data']:
|
||||
folder_path = os.path.join(current_dir, folder)
|
||||
if os.path.exists(folder_path) and os.path.isdir(folder_path):
|
||||
datas.append((folder_path, folder))
|
||||
|
||||
# 确定输出文件名
|
||||
output_name = app_name if app_name else "cursor动态账号注册机"
|
||||
print(f"输出文件名设置为: {output_name}")
|
||||
|
||||
# 生成 spec 文件内容
|
||||
spec_content = f"""# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
block_cipher = None
|
||||
|
||||
# 收集项目文件
|
||||
a = Analysis(
|
||||
['{main_script}'],
|
||||
pathex=['{current_dir}'],
|
||||
binaries=[],
|
||||
datas={datas},
|
||||
hiddenimports=[
|
||||
'colorama', 'requests', 'json', 'random', 'datetime', 'enum', 'dotenv',
|
||||
'tkinter', 'tkinter.messagebox', 'tkinter.ttk',
|
||||
'threading', 'queue', 'urllib', 'urllib.request', 'urllib.parse',
|
||||
'time', 'sys', 'os', 'traceback', 'logging', 'typing', 're', 'base64',
|
||||
'platform', 'collections'
|
||||
],
|
||||
hookspath=[],
|
||||
hooksconfig={{}},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
# 创建可执行文件
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='{output_name}',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=False,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=None,
|
||||
)
|
||||
"""
|
||||
|
||||
spec_file = 'cursor_pro_register.spec'
|
||||
with open(spec_file, 'w', encoding='utf-8') as f:
|
||||
f.write(spec_content)
|
||||
|
||||
print(f"✅ 已创建 {spec_file}")
|
||||
return True
|
||||
|
||||
def build_from_spec(keep_previous, app_name):
|
||||
"""从 spec 文件构建可执行文件"""
|
||||
print("开始从 spec 文件构建可执行文件...")
|
||||
|
||||
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}")
|
||||
|
||||
# 确定输出文件名
|
||||
output_name = app_name if app_name else "cursor动态账号注册机"
|
||||
|
||||
# 构建命令
|
||||
cmd = ["pyinstaller", "--workpath", build_dir, "cursor_pro_register.spec", "--clean", "--noupx"]
|
||||
print(f"执行命令: {' '.join(cmd)}")
|
||||
|
||||
try:
|
||||
# 运行 PyInstaller 使用 spec 文件
|
||||
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}")
|
||||
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=否)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"接收到的参数: 应用名称=\"{args.app_name}\", 保留旧版本={bool(args.keep_previous)}")
|
||||
|
||||
# 安装必要的依赖
|
||||
if not install_requirements():
|
||||
print("❌ 安装依赖失败,打包终止")
|
||||
sys.exit(1)
|
||||
|
||||
# 创建 spec 文件
|
||||
if not create_spec_file(args.app_name):
|
||||
print("❌ 创建 spec 文件失败,打包终止")
|
||||
sys.exit(1)
|
||||
|
||||
# 从 spec 文件构建
|
||||
if build_from_spec(bool(args.keep_previous), args.app_name):
|
||||
print("\n打包过程完成!")
|
||||
else:
|
||||
print("\n打包过程出现错误,请检查上面的日志信息")
|
||||
|
||||
input("按任意键退出...")
|
||||
Reference in New Issue
Block a user