From f67e1fb0da58a6ca40652a8bca4360cc68a265aa Mon Sep 17 00:00:00 2001 From: adaptronic-label printer final Date: Tue, 24 Feb 2026 11:52:42 +0200 Subject: [PATCH] Replace prepare_ghostscript.bat with Python script to fix nested for/if batch parser bug --- build_windows.bat | 2 +- prepare_ghostscript.bat | 6 ++- prepare_ghostscript.py | 115 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 prepare_ghostscript.py diff --git a/build_windows.bat b/build_windows.bat index 881799f..fc4caf7 100644 --- a/build_windows.bat +++ b/build_windows.bat @@ -50,7 +50,7 @@ echo. REM Copy GhostScript binaries for bundling (optional but strongly recommended) echo [4/6] Preparing GhostScript for bundling... -call prepare_ghostscript.bat +python prepare_ghostscript.py echo. REM Check that SumatraPDF.exe exists before building diff --git a/prepare_ghostscript.bat b/prepare_ghostscript.bat index 7d5ef0a..c6771d6 100644 --- a/prepare_ghostscript.bat +++ b/prepare_ghostscript.bat @@ -22,6 +22,10 @@ set GS_BIN_SRC= set GS_LIB_SRC= set GS_EXE= +REM Pre-assign ProgramFiles(x86) to avoid batch parser choking on the parentheses +set "PF64=%ProgramFiles%" +set "PF32=%ProgramFiles(x86)%" + echo. echo ============================================================ echo GhostScript Bundle Preparation @@ -29,7 +33,7 @@ echo ============================================================ echo. REM ---- Search for GhostScript in both Program Files locations ---- -for %%P in ("%ProgramFiles%" "%ProgramFiles(x86)%") do ( +for %%P in ("%PF64%" "%PF32%") do ( if exist "%%~P\gs" ( for /d %%V in ("%%~P\gs\gs*") do ( if exist "%%~V\bin\gswin64c.exe" ( diff --git a/prepare_ghostscript.py b/prepare_ghostscript.py new file mode 100644 index 0000000..730bb87 --- /dev/null +++ b/prepare_ghostscript.py @@ -0,0 +1,115 @@ +""" +prepare_ghostscript.py +Finds the system GhostScript installation and copies the files needed for +bundling into conf\ghostscript\ + +Files copied: + conf\ghostscript\bin\gswin64c.exe (or gswin32c.exe) + conf\ghostscript\bin\gsdll64.dll (or gsdll32.dll) + conf\ghostscript\lib\*.ps (PostScript init files) + +Run this ONCE before building the exe with build_windows.bat. +""" + +import os +import shutil +import glob +import sys + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +DEST_BIN = os.path.join(SCRIPT_DIR, "conf", "ghostscript", "bin") +DEST_LIB = os.path.join(SCRIPT_DIR, "conf", "ghostscript", "lib") + +SEARCH_ROOTS = [ + os.environ.get("ProgramFiles", r"C:\Program Files"), + os.environ.get("ProgramFiles(x86)", r"C:\Program Files (x86)"), + os.environ.get("ProgramW6432", r"C:\Program Files"), +] + +FLAVOURS = [ + ("gswin64c.exe", "gsdll64.dll"), + ("gswin32c.exe", "gsdll32.dll"), +] + +print() +print("=" * 60) +print(" GhostScript Bundle Preparation") +print("=" * 60) +print() + + +def find_ghostscript(): + """Return (bin_dir, lib_dir, exe_name, dll_name) or None.""" + for root in dict.fromkeys(r for r in SEARCH_ROOTS if r): # unique, preserve order + gs_root = os.path.join(root, "gs") + if not os.path.isdir(gs_root): + continue + # Each versioned sub-folder, newest first + versions = sorted( + [d for d in glob.glob(os.path.join(gs_root, "gs*")) if os.path.isdir(d)], + reverse=True, + ) + for ver_dir in versions: + bin_dir = os.path.join(ver_dir, "bin") + lib_dir = os.path.join(ver_dir, "lib") + for exe, dll in FLAVOURS: + if os.path.isfile(os.path.join(bin_dir, exe)): + print(f"Found GhostScript: {ver_dir}") + return bin_dir, lib_dir, exe, dll + return None + + +result = find_ghostscript() + +if result is None: + print("WARNING: GhostScript is NOT installed on this machine.") + print() + print(" The exe will still build successfully, but GhostScript will") + print(" NOT be bundled. On the target machine the app will fall back") + print(" to SumatraPDF for printing (which may produce dotted output).") + print() + print(" To get sharp vector-quality printing, install GhostScript:") + print(" https://ghostscript.com/releases/gsdnld.html") + print(" Then re-run this script before building.") + print() + sys.exit(0) + +src_bin, src_lib, exe_name, dll_name = result + +# Create destination folders +os.makedirs(DEST_BIN, exist_ok=True) +os.makedirs(DEST_LIB, exist_ok=True) + +# Copy executable and DLL +print("Copying GhostScript binaries...") +for fname in (exe_name, dll_name): + src = os.path.join(src_bin, fname) + dst = os.path.join(DEST_BIN, fname) + if os.path.isfile(src): + shutil.copy2(src, dst) + print(f" + {fname}") + else: + print(f" WARNING: {fname} not found in {src_bin}") + +# Copy lib/ (PostScript init files .ps) +print() +print("Copying GhostScript lib (PostScript init files)...") +ps_files = glob.glob(os.path.join(src_lib, "*.ps")) +for ps in ps_files: + shutil.copy2(ps, DEST_LIB) +print(f" + {len(ps_files)} .ps files copied from {src_lib}") + +# Report +bin_count = len(os.listdir(DEST_BIN)) +lib_count = len(os.listdir(DEST_LIB)) + +print() +print("=" * 60) +print(" GhostScript prepared successfully in conf\\ghostscript\\") +print("=" * 60) +print() +print(f" bin\\ : {bin_count} file(s)") +print(f" lib\\ : {lib_count} file(s)") +print() +print("GhostScript will be embedded into LabelPrinter.exe at build time.") +print()