diff --git a/build/build_utils.py b/build/build_utils.py index 7535e12..725cad4 100644 --- a/build/build_utils.py +++ b/build/build_utils.py @@ -175,6 +175,23 @@ def get_pyinstaller_args(platform: str) -> Tuple[List[str], List[str]]: "--version-file=Auto-Wall.spec.version" if Path("Auto-Wall.spec.version").exists() else None, ]) base_args = [arg for arg in base_args if arg is not None] + + # Bundle MSVC runtime DLLs so the exe is truly standalone. + # PyInstaller excludes these by default, causing DLL errors on machines + # without the VC++ redistributable installed. + import os + _msvc_dlls = [ + 'VCRUNTIME140.dll', + 'VCRUNTIME140_1.dll', + 'MSVCP140.dll', + 'MSVCP140_1.dll', + 'MSVCP140_2.dll', + ] + sysroot = os.environ.get('SystemRoot', r'C:\Windows') + for _dll in _msvc_dlls: + _path = os.path.join(sysroot, 'System32', _dll) + if os.path.exists(_path): + base_args.append(f'--add-binary={_path}{separator}.') elif platform == "macos": base_args.extend([ diff --git a/build/platforms/windows.py b/build/platforms/windows.py index 577ddb7..1e6786f 100644 --- a/build/platforms/windows.py +++ b/build/platforms/windows.py @@ -3,6 +3,7 @@ """ import shutil +import urllib.request from pathlib import Path from typing import List @@ -11,6 +12,9 @@ ensure_directory ) +VCREDIST_URL = "https://aka.ms/vs/17/release/vc_redist.x64.exe" +VCREDIST_FILENAME = "vc_redist.x64.exe" + class WindowsBuilder: """Windows platform builder""" @@ -38,32 +42,24 @@ def build_all(self, executable_path: Path) -> List[tuple]: return results def create_zip_distribution(self, executable_path: Path) -> Path: - """Create a ZIP distribution with executable and resources""" + """Create a ZIP distribution with the standalone executable""" print_status("Creating ZIP distribution...") - # Create temporary directory for ZIP contents zip_dir = Path("Auto-Wall-Windows") if zip_dir.exists(): shutil.rmtree(zip_dir) - zip_dir.mkdir() - # Copy executable shutil.copy2(executable_path, zip_dir / "Auto-Wall.exe") - # Copy documentation for doc_file in ["README.md", "LICENSE"]: doc_path = Path(doc_file) if doc_path.exists(): shutil.copy2(doc_path, zip_dir / doc_file) - # Create ZIP file zip_name = f"Auto-Wall-{self.version}-Windows" zip_path = self.dist_path / f"{zip_name}.zip" - shutil.make_archive(str(self.dist_path / zip_name), 'zip', str(zip_dir)) - - # Clean up shutil.rmtree(zip_dir) if zip_path.exists():