#!/usr/bin/env python3 import os import sys import subprocess import platform from pathlib import Path def clear_screen(): os.system('cls' if os.name == 'nt' else 'clear') def print_header(): print("=" * 60) print(" PYINSTALLER AUTOMATION TOOL") print("=" * 60) print() def get_script_path(): while True: script_path = input("Enter the full path to the Python script: ").strip() script_path = script_path.strip('"\'') if not script_path: print("Path cannot be empty!") continue script_path = Path(script_path) if not script_path.exists(): print("File not found!") continue if script_path.suffix.lower() != '.py': print("File must have .py extension!") continue return script_path def select_mode(): print("\nCOMPILATION MODE:") print("1. One-file (single file)") print("2. One-directory (folder with dependencies)") while True: choice = input("\nChoose mode (1-2): ").strip() if choice == '1': return True elif choice == '2': return False print("Invalid option! Choose 1 or 2.") def select_console(): print("\nEXECUTION MODE:") print("1. With console (default)") print("2. Without console (GUI/windowed)") while True: choice = input("\nChoose mode (1-2): ").strip() if choice == '1': return False elif choice == '2': return True print("Invalid option! Choose 1 or 2.") def select_optimization(): print("\nOPTIMIZATION:") print("1. No optimization (default)") print("2. Basic optimization (-O)") print("3. Maximum optimization (-OO)") optimizations = {'1': None, '2': '-O', '3': '-OO'} while True: choice = input("\nChoose optimization (1-3): ").strip() if choice in optimizations: return optimizations[choice] print("Invalid option! Choose 1-3.") def select_icon(): print("\nCUSTOM ICON:") print("1. No custom icon") print("2. Use custom icon") while True: choice = input("\nChoose option (1-2): ").strip() if choice == '1': return None elif choice == '2': icon_path = input("Enter path to .ico (Windows) or .png (Linux/Mac) file: ").strip() icon_path = icon_path.strip('"\'') if Path(icon_path).exists(): return icon_path else: print("Icon file not found!") continue print("Invalid option! Choose 1 or 2.") def select_additional_files(): print("\nADDITIONAL FILES:") print("1. Do not add files") print("2. Add files/directories") while True: choice = input("\nChoose option (1-2): ").strip() if choice == '1': return [] elif choice == '2': files = [] while True: file_path = input("Enter file/directory path (or Enter to finish): ").strip() if not file_path: break file_path = file_path.strip('"\'') if Path(file_path).exists(): files.append(file_path) print(f"File added: {file_path}") else: print("File not found!") return files print("Invalid option! Choose 1 or 2.") def select_upx(): print("\nUPX COMPRESSION:") print("1. Enable UPX compression (smaller files)") print("2. Disable UPX compression") while True: choice = input("\nChoose option (1-2): ").strip() if choice == '1': return False elif choice == '2': return True print("Invalid option! Choose 1 or 2.") def build_command(script_path, onefile, windowed, optimization, icon, additional_files, noupx): cmd = ['pyinstaller'] if onefile: cmd.append('--onefile') else: cmd.append('--onedir') if windowed: cmd.append('--windowed') if icon: cmd.extend(['--icon', icon]) if optimization: cmd.extend(['--python-option', optimization]) if noupx: cmd.append('--noupx') for file in additional_files: if os.path.isdir(file): cmd.extend(['--add-data', f'{file}{os.pathsep}{file}']) else: cmd.extend(['--add-data', f'{file}{os.pathsep}.']) exe_name = script_path.stem cmd.extend(['--name', exe_name]) cmd.append(str(script_path)) return cmd def run_pyinstaller(command): print(f"\nExecuting: {' '.join(command)}") print("\nCompiling... This may take a few minutes...") print("-" * 60) try: result = subprocess.run(command, check=True, capture_output=True, text=True) print("Compilation completed successfully!") return True except subprocess.CalledProcessError as e: print(f"Error during compilation:") if e.stderr: print(f"Stderr: {e.stderr}") if e.stdout: print(f"Stdout: {e.stdout}") return False except FileNotFoundError: print("PyInstaller not found! Make sure it is installed.") print("Install with: pip install pyinstaller") return False def show_summary(script_path, onefile, windowed, optimization, icon, additional_files, output_dir, noupx): clear_screen() print_header() print("COMPILATION SUMMARY:") print(f"Script: {script_path}") print(f"Mode: {'One-file' if onefile else 'One-directory'}") print(f"Console: {'No' if windowed else 'Yes'}") print(f"Optimization: {optimization or 'None'}") print(f"Icon: {icon or 'Default'}") print(f"UPX: {'Disabled' if noupx else 'Enabled'}") print(f"Additional files: {len(additional_files)}") print(f"Output directory: {output_dir}") print("-" * 60) def main(): clear_screen() print_header() try: subprocess.run(['pyinstaller', '--version'], capture_output=True, check=True) except (subprocess.CalledProcessError, FileNotFoundError): print("PyInstaller not found!") install = input("Do you want to install PyInstaller? (y/n): ").strip().lower() if install == 'y': subprocess.run([sys.executable, '-m', 'pip', 'install', 'pyinstaller']) else: print("Exiting...") return script_path = get_script_path() onefile = select_mode() windowed = select_console() optimization = select_optimization() icon = select_icon() additional_files = select_additional_files() noupx = select_upx() output_dir = Path("dist") show_summary(script_path, onefile, windowed, optimization, icon, additional_files, output_dir, noupx) confirm = input("\nProceed with compilation? (y/n): ").strip().lower() if confirm != 'y': print("Compilation canceled!") return command = build_command(script_path, onefile, windowed, optimization, icon, additional_files, noupx) success = run_pyinstaller(command) if success: print(f"\nCompilation completed!") print(f"Executable generated in: {output_dir}") if onefile: exe_name = script_path.stem if os.name == 'nt': exe_name += '.exe' exe_path = output_dir / exe_name else: exe_dir = output_dir / script_path.stem exe_name = script_path.stem if os.name == 'nt': exe_name += '.exe' exe_path = exe_dir / exe_name print(f"File: {exe_path}") if exe_path.exists(): print("✅ Executable successfully created!") else: print("⚠️ Executable might not have been created correctly.") else: print("\nCompilation failed! Check the errors above.") if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\nProgram interrupted by user!") except Exception as e: print(f"Unexpected error: {e}")