ArticleReplaceBatch/deepseek-clien/clear_setup.py

267 lines
7.7 KiB
Python
Raw Normal View History

2025-08-06 15:57:14 +08:00
#!/usr/bin/env python3
"""
完全清理环境并重新构建的脚本
"""
import os
import sys
import shutil
import glob
import subprocess
from pathlib import Path
def deep_cleanup():
"""深度清理所有相关文件"""
print("开始深度清理...")
# 要清理的目录
dirs_to_clean = [
"build", "dist", "__pycache__",
".pytest_cache", "*.egg-info"
]
# 要清理的文件模式
files_to_clean = [
"*.exe", "*.spec", "*_encrypted*",
"setup_main.py", "setup_validator.py",
"*.pyc", "*.pyo"
]
# 清理目录
for dir_pattern in dirs_to_clean:
for dir_path in glob.glob(dir_pattern):
if os.path.exists(dir_path):
print(f"删除目录: {dir_path}")
try:
shutil.rmtree(dir_path)
except Exception as e:
print(f"删除 {dir_path} 失败: {e}")
# 清理文件
for file_pattern in files_to_clean:
for file_path in glob.glob(file_pattern):
if os.path.exists(file_path):
print(f"删除文件: {file_path}")
try:
os.remove(file_path)
except Exception as e:
print(f"删除 {file_path} 失败: {e}")
# 清理Python缓存
for root, dirs, files in os.walk("."):
for dir_name in dirs[:]:
if dir_name == "__pycache__":
pycache_path = os.path.join(root, dir_name)
print(f"删除缓存: {pycache_path}")
try:
shutil.rmtree(pycache_path)
dirs.remove(dir_name)
except Exception as e:
print(f"删除缓存失败: {e}")
print("清理完成")
def create_single_file_setup(script_name, output_name, base_type="Console"):
"""创建单文件构建的setup.py"""
setup_content = f'''
import sys
from cx_Freeze import setup, Executable
# 基础构建选项
build_exe_options = {{
"packages": [
"mysql.connector", "cryptography", "uuid", "hashlib",
"datetime", "platform", "subprocess", "json",
"tempfile", "atexit", "ctypes"
],
"build_exe": "dist_{output_name.replace('.exe', '')}",
"excludes": ["unittest", "test"]
}}
# 如果是主程序添加tkinter和pyperclip
if "{script_name}" == "main.py":
build_exe_options["packages"].extend(["tkinter", "pyperclip"])
executables = [
Executable("{script_name}", base="{base_type}")
]
setup(
name="{output_name.replace('.exe', '')}",
version="1.0",
options={{"build_exe": build_exe_options}},
executables=executables
)
'''
return setup_content
def build_single_executable(script_name, output_name, base_type="Console"):
"""构建单个可执行文件"""
print(f"构建 {script_name} -> {output_name}")
# 创建临时setup文件
setup_filename = f"setup_{output_name.replace('.exe', '')}.py"
setup_content = create_single_file_setup(script_name, output_name, base_type)
try:
with open(setup_filename, "w", encoding="utf-8") as f:
f.write(setup_content)
# 运行构建
result = subprocess.run(
[sys.executable, setup_filename, "build"],
capture_output=True, text=True, cwd="."
)
success = result.returncode == 0
if success:
print(f"{output_name} 构建成功")
else:
print(f"{output_name} 构建失败:")
print(result.stderr)
return success
except Exception as e:
print(f"构建 {output_name} 时发生异常: {e}")
return False
finally:
# 清理临时文件
if os.path.exists(setup_filename):
try:
os.remove(setup_filename)
except:
pass
def organize_final_dist():
"""整理最终的发布目录"""
print("整理最终发布目录...")
final_dir = Path("dist_final")
final_dir.mkdir(exist_ok=True)
# 收集所有构建的文件
dist_dirs = [d for d in Path(".").iterdir() if d.is_dir() and d.name.startswith("dist_")]
all_files = {}
for dist_dir in dist_dirs:
for file_path in dist_dir.rglob("*"):
if file_path.is_file():
all_files[file_path.name] = file_path
# 复制文件到最终目录
for filename, filepath in all_files.items():
dest_path = final_dir / filename
if not dest_path.exists() or filename.endswith('.exe'):
try:
shutil.copy2(filepath, dest_path)
print(f"复制: {filename}")
except Exception as e:
print(f"复制 {filename} 失败: {e}")
# 重命名主程序
main_exe = final_dir / "main.exe"
target_exe = final_dir / "EXE加密工具.exe"
if main_exe.exists() and not target_exe.exists():
try:
main_exe.rename(target_exe)
print("主程序重命名为: EXE加密工具.exe")
except Exception as e:
print(f"重命名失败: {e}")
# 清理临时构建目录
for dist_dir in dist_dirs:
try:
shutil.rmtree(dist_dir)
except:
pass
print(f"最终文件已整理到: {final_dir.absolute()}")
return final_dir
def try_pyinstaller_fallback():
"""尝试使用PyInstaller作为备选方案"""
print("尝试使用PyInstaller作为备选方案...")
try:
# 检查PyInstaller是否可用
result = subprocess.run([sys.executable, "-c", "import PyInstaller"],
capture_output=True)
if result.returncode != 0:
print("PyInstaller未安装正在安装...")
subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"],
check=True)
# 使用PyInstaller构建
commands = [
[sys.executable, "-m", "PyInstaller", "--onefile", "--windowed",
"--name=EXE加密工具", "main.py"],
[sys.executable, "-m", "PyInstaller", "--onefile", "--console",
"validator.py"]
]
for cmd in commands:
print(f"运行: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"PyInstaller构建失败: {result.stderr}")
return False
print("PyInstaller构建成功文件位于 dist/ 目录")
return True
except Exception as e:
print(f"PyInstaller构建异常: {e}")
return False
def main():
"""主函数"""
print("=== EXE加密工具构建脚本 ===")
# 1. 深度清理
deep_cleanup()
# 2. 尝试使用cx_Freeze分别构建
print("\n尝试使用cx_Freeze构建...")
builds = [
("main.py", "main.exe", "Win32GUI"),
("validator.py", "validator.exe", "Console")
]
all_success = True
for script, output, base in builds:
if not build_single_executable(script, output, base):
all_success = False
break
if all_success:
final_dir = organize_final_dist()
print(f"\n✅ cx_Freeze构建成功")
print(f"📁 文件位置: {final_dir.absolute()}")
return True
# 3. 如果cx_Freeze失败尝试PyInstaller
print("\n❌ cx_Freeze构建失败尝试PyInstaller...")
deep_cleanup() # 再次清理
if try_pyinstaller_fallback():
print("\n✅ PyInstaller构建成功")
print("📁 文件位置: dist/")
return True
print("\n❌ 所有构建方法都失败了")
print("建议手动检查依赖和环境配置")
return False
if __name__ == "__main__":
success = main()
if not success:
print("失败")