From fdfdc879d7f21f51bfd651169093643335a5298a Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 5 Oct 2026 21:23:13 -0400 Subject: [PATCH] Windows: no console window with the app, and the Start Menu shortcut gets its icon (#57) - printcraft.exe release builds use the GUI subsystem, so launching it no longer opens a console window next to it (debug builds keep the console). - The MSI's Icon id gains its .ico extension: Windows Installer requires it for advertised shortcuts and ARPPRODUCTICON, so the Start Menu shortcut and Add/Remove Programs showed a blank icon. - Guards: package.ps1 checks the PE subsystem of both binaries (app = GUI, CLI = console) before packaging; packaging-lint fails on an Icon id without .ico/.exe. - The shortcut's description said "image editor"; it's a PDF workbench. Reported, with the exact fixes, by @MikailuReeves. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/packaging-lint.yml | 4 ++++ apps/printcraft/src/main.rs | 4 ++++ packaging/windows/package.ps1 | 13 +++++++++++++ packaging/windows/printcraft.wxs | 12 +++++++----- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/.github/workflows/packaging-lint.yml b/.github/workflows/packaging-lint.yml index 50e4b013..29817c7e 100644 --- a/.github/workflows/packaging-lint.yml +++ b/.github/workflows/packaging-lint.yml @@ -47,6 +47,10 @@ jobs: - name: XML, desktop entry, AppStream, Flatpak manifest run: | xmllint --noout packaging/windows/printcraft.wxs packaging/macos/*.plist* packaging/linux/*.xml* + # Windows Installer needs Icon ids ending in .ico or .exe, or shortcuts show a blank icon (#57). + if grep -oE '"$RUNNER_TEMP/ai.storyteller.printcraft.metainfo.xml" appstreamcli validate --no-net --explain "$RUNNER_TEMP/ai.storyteller.printcraft.metainfo.xml" diff --git a/apps/printcraft/src/main.rs b/apps/printcraft/src/main.rs index 887fe13e..390b3c0a 100644 --- a/apps/printcraft/src/main.rs +++ b/apps/printcraft/src/main.rs @@ -11,6 +11,10 @@ //! loopback port and writes `{"port", "token", "pid"}` to `` (owner-only permissions). //! Agents then drive it with `printcraft-cli ui --control …`. +// Release builds on Windows are GUI-subsystem programs, so launching the app doesn't open a console +// window next to it (#57). `--version` and diagnostics then go nowhere when started from a terminal +// (std ignores the missing console handles, so nothing fails); debug builds keep the console. +#![cfg_attr(all(windows, not(debug_assertions)), windows_subsystem = "windows")] #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] use printcraft_ui_egui::PrintCraftApp; diff --git a/packaging/windows/package.ps1 b/packaging/windows/package.ps1 index a5d77330..71b23c72 100644 --- a/packaging/windows/package.ps1 +++ b/packaging/windows/package.ps1 @@ -65,6 +65,19 @@ if (-not $SkipBuild) { } $Bin = Join-Path $TargetDir "$Target\release" + +# The PE optional header's Subsystem field: 2 = Windows GUI, 3 = console. The app must be GUI (no +# console window opens with it, #57); the CLI must stay console so its output reaches the terminal. +function Get-PeSubsystem([string] $Path) { + $bytes = [System.IO.File]::ReadAllBytes($Path) + $pe = [BitConverter]::ToInt32($bytes, 0x3C) + return [BitConverter]::ToUInt16($bytes, $pe + 0x5C) +} +foreach ($check in @(@('printcraft.exe', 2), @('printcraft-cli.exe', 3))) { + $subsystem = Get-PeSubsystem (Join-Path $Bin $check[0]) + if ($subsystem -ne $check[1]) { throw "$($check[0]) has PE subsystem $subsystem, expected $($check[1])" } + Write-Output "ok $($check[0]): PE subsystem $subsystem" +} $Stage = Join-Path $TargetDir "windows-package\$Arch" Remove-Item -Recurse -Force $Stage -ErrorAction SilentlyContinue New-Item -ItemType Directory -Force -Path $Stage | Out-Null diff --git a/packaging/windows/printcraft.wxs b/packaging/windows/printcraft.wxs index e212af11..4c21d81a 100644 --- a/packaging/windows/printcraft.wxs +++ b/packaging/windows/printcraft.wxs @@ -17,15 +17,17 @@ Scope="perMachine" Compressed="yes" Language="1033"> - + - - + + + @@ -45,8 +47,8 @@ + Description="PrintCraft PDF workbench" WorkingDirectory="INSTALLFOLDER" Advertise="yes" + Icon="PrintcraftIcon.ico" IconIndex="0" />