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 <noreply@anthropic.com>
This commit is contained in:
Brandon ThomasandClaude Opus 5.5 committed 2026-10-05 21:33:17 -04:00
1 parent d7749e6379
commit fdfdc879d7
4 files changed
+28 -5

No files matched your search

+4
View File
@@ -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 '<Icon Id="[^"]*"' packaging/windows/printcraft.wxs | grep -vE '\.(ico|exe)"$'; then
echo "::error file=packaging/windows/printcraft.wxs::Icon Id must end in .ico or .exe"; exit 1
fi
desktop-file-validate packaging/linux/ai.storyteller.printcraft.desktop
sed -e 's/@VERSION@/0.0.0/' -e 's/@DATE@/2026-01-01/' packaging/linux/ai.storyteller.printcraft.metainfo.xml.in >"$RUNNER_TEMP/ai.storyteller.printcraft.metainfo.xml"
appstreamcli validate --no-net --explain "$RUNNER_TEMP/ai.storyteller.printcraft.metainfo.xml"
+4
View File
@@ -11,6 +11,10 @@
//! loopback port and writes `{"port", "token", "pid"}` to `<file>` (owner-only permissions).
//! Agents then drive it with `printcraft-cli ui --control <file> <method> …`.
// 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;
+13
View File
@@ -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
+7 -5
View File
@@ -17,15 +17,17 @@
Scope="perMachine"
Compressed="yes"
Language="1033">
<SummaryInformation Description="PrintCraft image editor" Manufacturer="Learning Machines LLC" />
<SummaryInformation Description="PrintCraft PDF workbench" Manufacturer="Learning Machines LLC" />
<!-- Same-version upgrades let successive pre-releases of one X.Y.Z replace each other
(MSI versions are numeric, so 1.2.3-rc.1 and 1.2.3-rc.2 are both 1.2.3). -->
<MajorUpgrade AllowSameVersionUpgrades="yes"
DowngradeErrorMessage="A newer version of PrintCraft is already installed." />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<Icon Id="PrintcraftIcon" SourceFile="$(var.IconPath)" />
<Property Id="ARPPRODUCTICON" Value="PrintcraftIcon" />
<!-- Windows Installer requires an Icon id ending in .ico or .exe, or advertised shortcuts and
Add/Remove Programs show a blank icon (#57). -->
<Icon Id="PrintcraftIcon.ico" SourceFile="$(var.IconPath)" />
<Property Id="ARPPRODUCTICON" Value="PrintcraftIcon.ico" />
<Property Id="ARPURLINFOABOUT" Value="https://getartcraft.com/apps/printcraft" />
<Property Id="ARPURLUPDATEINFO" Value="https://getartcraft.com/apps/printcraft" />
<Property Id="ARPHELPLINK" Value="https://discord.gg/artcraft" />
@@ -45,8 +47,8 @@
<Component Id="PrintcraftApp" Guid="E724C1C6-091F-4E21-A685-80D089FDBE21">
<File Id="PrintcraftExe" Source="$(var.BinDir)\printcraft.exe" KeyPath="yes">
<Shortcut Id="StartMenuShortcut" Directory="ProgramMenuFolder" Name="PrintCraft"
Description="PrintCraft image editor" WorkingDirectory="INSTALLFOLDER" Advertise="yes"
Icon="PrintcraftIcon" IconIndex="0" />
Description="PrintCraft PDF workbench" WorkingDirectory="INSTALLFOLDER" Advertise="yes"
Icon="PrintcraftIcon.ico" IconIndex="0" />
</File>
<RegistryValue Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\App Paths\printcraft.exe" Value="[#PrintcraftExe]" Type="string" />