Windows client: per-user installer + portable zip as the default download — a stable exe path Steam can launch (overlay, Big Picture); MSIX stays for the Store
#349
A user reported the Windows client can't be launched via Big Picture and the Steam overlay never appears. The cause isn't UWP — the client is full-trust Win32 under MSIX too — it's the MSIX install shape: the exe lands under the ACL'd WindowsApps dir Steam's Add a Non-Steam Game picker can't browse, and alias/shell:AppsFolder activation defeats the overlay's GameOverlayRenderer64.dll injection (Steam must spawn the exe itself from a normal path). Same reason the overlay doesn't work for Store/Game Pass titles.
So the default download becomes a classic per-user Inno Setup exe (no UAC, %LOCALAPPDATA%\Programs\Punktfunk), with a portable zip beside it. The MSIX keeps being built and published for Microsoft Store compatibility. All three artifacts are packed from the one layout pack-msix.ps1 already assembles.
What's in here
punktfunk-client.iss — re-creates the manifest's declarative grants per-user in HKCU: punktfunk:// scheme, flat Start entries (Punktfunk + Punktfunk Console), {app} on the user PATH for the punktfunk CLI (what the Playnite importer shells to). Fetches the Windows App Runtime when missing (ssPostInstall, so silent installs get it too; failure is non-fatal and points at the docs). PATH append/removal are the host installer's helpers retargeted to HKCU.
pack-client-installer.ps1 — consumes pack-msix.ps1's layout, signs the four exes individually (the MSIX only signs its container), emits punktfunk-client-setup-<ver>_<arch>.exe + punktfunk-client-windows_<ver>_<arch>-portable.zip. Same signing precedence + fail-closed-on-v*-tags rule as the sibling scripts. No .cer: unlike an MSIX, an exe runs regardless of signer trust.
windows-client.yml — pack step after the MSIX (both arches), publish to the generic registry under canary//latest aliases (punktfunk-client-setup_<arch>.exe, punktfunk-client-windows_<arch>-portable.zip), attach to the Gitea release on tags.
deeplink.rs — write_shortcut targeted the app-execution alias unconditionally, which doesn't exist without package identity; it now targets the alias when packaged (survives per-update path changes) and current_exe() when not (stable path, no alias). The package-identity probe is now deeplink::has_package_identity(), shared with main.rs's AppUserModelID logic instead of being inlined twice.
User-facing fact changed? Yes — install/update/uninstall steps and the artifact set. Updated in this PR: install-client.md (installer as the default, a Launching through Steam section, portable/MSIX as alternates, MSIX→installer migration note — packaged AppData goes with the package, so one re-pair), channels.md, uninstall.md, clients.md, and data/platforms.json + the byte-copy snapshot (check-docs-drift.sh passes).
Verification — docs drift gate green, cargo fmt --check green, workflow YAML parses. The Rust change compiles only on the Windows runner (this box can't cross-build the MSVC deps) — the PR's build/clippy/test legs are the gate for that, and the packaging steps first exercise for real on the merge-to-main canary run.
Follow-ups, deliberately not here: unom.Punktfunk on the winget source (needs client manifest templates + the source republish job), and an in-app "Add to Steam" button.
A user reported the Windows client can't be launched via Big Picture and the Steam overlay never appears. The cause isn't UWP — the client is full-trust Win32 under MSIX too — it's the MSIX **install shape**: the exe lands under the ACL'd `WindowsApps` dir Steam's *Add a Non-Steam Game* picker can't browse, and alias/`shell:AppsFolder` activation defeats the overlay's `GameOverlayRenderer64.dll` injection (Steam must spawn the exe itself from a normal path). Same reason the overlay doesn't work for Store/Game Pass titles.
So the default download becomes a classic per-user Inno Setup exe (no UAC, `%LOCALAPPDATA%\Programs\Punktfunk`), with a portable zip beside it. The MSIX keeps being built and published for Microsoft Store compatibility. All three artifacts are packed from the **one** layout `pack-msix.ps1` already assembles.
**What's in here**
- `punktfunk-client.iss` — re-creates the manifest's declarative grants per-user in HKCU: `punktfunk://` scheme, flat Start entries (Punktfunk + Punktfunk Console), `{app}` on the user PATH for the `punktfunk` CLI (what the Playnite importer shells to). Fetches the Windows App Runtime when missing (`ssPostInstall`, so silent installs get it too; failure is non-fatal and points at the docs). PATH append/removal are the host installer's helpers retargeted to HKCU.
- `pack-client-installer.ps1` — consumes `pack-msix.ps1`'s layout, signs the four exes individually (the MSIX only signs its container), emits `punktfunk-client-setup-<ver>_<arch>.exe` + `punktfunk-client-windows_<ver>_<arch>-portable.zip`. Same signing precedence + fail-closed-on-`v*`-tags rule as the sibling scripts. No `.cer`: unlike an MSIX, an exe runs regardless of signer trust.
- `windows-client.yml` — pack step after the MSIX (both arches), publish to the generic registry under `canary/`/`latest` aliases (`punktfunk-client-setup_<arch>.exe`, `punktfunk-client-windows_<arch>-portable.zip`), attach to the Gitea release on tags.
- `deeplink.rs` — `write_shortcut` targeted the app-execution alias unconditionally, which doesn't exist without package identity; it now targets the alias when packaged (survives per-update path changes) and `current_exe()` when not (stable path, no alias). The package-identity probe is now `deeplink::has_package_identity()`, shared with `main.rs`'s AppUserModelID logic instead of being inlined twice.
**User-facing fact changed?** Yes — install/update/uninstall steps and the artifact set. Updated in this PR: `install-client.md` (installer as the default, a *Launching through Steam* section, portable/MSIX as alternates, MSIX→installer migration note — packaged AppData goes with the package, so one re-pair), `channels.md`, `uninstall.md`, `clients.md`, and `data/platforms.json` + the byte-copy snapshot (`check-docs-drift.sh` passes).
**Verification** — docs drift gate green, `cargo fmt --check` green, workflow YAML parses. The Rust change compiles only on the Windows runner (this box can't cross-build the MSVC deps) — the PR's build/clippy/test legs are the gate for that, and the packaging steps first exercise for real on the merge-to-main canary run.
Follow-ups, deliberately not here: `unom.Punktfunk` on the winget source (needs client manifest templates + the source republish job), and an in-app "Add to Steam" button.
A user report: launching via Big Picture doesn't work and the Steam overlay never appears.
Not because the app is UWP (it's full-trust Win32 under MSIX too) but because of the MSIX
install SHAPE: the exe lives under the ACL'd WindowsApps dir Steam's non-Steam-game picker
can't browse, and alias/shell:AppsFolder activation defeats the overlay's injection — Steam
must spawn the exe itself from a normal path.
- punktfunk-client.iss: per-user (no UAC) install to %LOCALAPPDATA%\Programs\Punktfunk.
Re-creates the manifest's grants in HKCU (punktfunk:// scheme, Start entries, {app} on the
user PATH for the punktfunk CLI) and fetches the Windows App Runtime when missing.
- pack-client-installer.ps1: consumes pack-msix.ps1's layout (one assembly, three artifacts),
signs the four exes individually, emits setup.exe + a portable zip. Same signing backends
and fail-closed-on-tags rule as the sibling scripts; no .cer (an exe runs untrusted).
- windows-client.yml: pack step after the MSIX, publish + release-attach the new artifacts
(canary/latest aliases punktfunk-client-setup_<arch>.exe, ..._<arch>-portable.zip).
- deeplink.rs: write_shortcut targets the app-execution alias only under package identity;
unpackaged installs have no alias but a stable path, so they target current_exe().
has_package_identity() now shared with main.rs's AppUserModelID probe.
- docs: install-client (installer default + a 'Launching through Steam' section + MSIX/portable
as alternates), channels, uninstall, clients, platforms.json (both copies, drift check green).
enricobuehler
scheduled this pull request to auto merge when all checks succeed 2026-08-19 23:05:31 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A user reported the Windows client can't be launched via Big Picture and the Steam overlay never appears. The cause isn't UWP — the client is full-trust Win32 under MSIX too — it's the MSIX install shape: the exe lands under the ACL'd
WindowsAppsdir Steam's Add a Non-Steam Game picker can't browse, and alias/shell:AppsFolderactivation defeats the overlay'sGameOverlayRenderer64.dllinjection (Steam must spawn the exe itself from a normal path). Same reason the overlay doesn't work for Store/Game Pass titles.So the default download becomes a classic per-user Inno Setup exe (no UAC,
%LOCALAPPDATA%\Programs\Punktfunk), with a portable zip beside it. The MSIX keeps being built and published for Microsoft Store compatibility. All three artifacts are packed from the one layoutpack-msix.ps1already assembles.What's in here
punktfunk-client.iss— re-creates the manifest's declarative grants per-user in HKCU:punktfunk://scheme, flat Start entries (Punktfunk + Punktfunk Console),{app}on the user PATH for thepunktfunkCLI (what the Playnite importer shells to). Fetches the Windows App Runtime when missing (ssPostInstall, so silent installs get it too; failure is non-fatal and points at the docs). PATH append/removal are the host installer's helpers retargeted to HKCU.pack-client-installer.ps1— consumespack-msix.ps1's layout, signs the four exes individually (the MSIX only signs its container), emitspunktfunk-client-setup-<ver>_<arch>.exe+punktfunk-client-windows_<ver>_<arch>-portable.zip. Same signing precedence + fail-closed-on-v*-tags rule as the sibling scripts. No.cer: unlike an MSIX, an exe runs regardless of signer trust.windows-client.yml— pack step after the MSIX (both arches), publish to the generic registry undercanary//latestaliases (punktfunk-client-setup_<arch>.exe,punktfunk-client-windows_<arch>-portable.zip), attach to the Gitea release on tags.deeplink.rs—write_shortcuttargeted the app-execution alias unconditionally, which doesn't exist without package identity; it now targets the alias when packaged (survives per-update path changes) andcurrent_exe()when not (stable path, no alias). The package-identity probe is nowdeeplink::has_package_identity(), shared withmain.rs's AppUserModelID logic instead of being inlined twice.User-facing fact changed? Yes — install/update/uninstall steps and the artifact set. Updated in this PR:
install-client.md(installer as the default, a Launching through Steam section, portable/MSIX as alternates, MSIX→installer migration note — packaged AppData goes with the package, so one re-pair),channels.md,uninstall.md,clients.md, anddata/platforms.json+ the byte-copy snapshot (check-docs-drift.shpasses).Verification — docs drift gate green,
cargo fmt --checkgreen, workflow YAML parses. The Rust change compiles only on the Windows runner (this box can't cross-build the MSVC deps) — the PR's build/clippy/test legs are the gate for that, and the packaging steps first exercise for real on the merge-to-main canary run.Follow-ups, deliberately not here:
unom.Punktfunkon the winget source (needs client manifest templates + the source republish job), and an in-app "Add to Steam" button.A user report: launching via Big Picture doesn't work and the Steam overlay never appears. Not because the app is UWP (it's full-trust Win32 under MSIX too) but because of the MSIX install SHAPE: the exe lives under the ACL'd WindowsApps dir Steam's non-Steam-game picker can't browse, and alias/shell:AppsFolder activation defeats the overlay's injection — Steam must spawn the exe itself from a normal path. - punktfunk-client.iss: per-user (no UAC) install to %LOCALAPPDATA%\Programs\Punktfunk. Re-creates the manifest's grants in HKCU (punktfunk:// scheme, Start entries, {app} on the user PATH for the punktfunk CLI) and fetches the Windows App Runtime when missing. - pack-client-installer.ps1: consumes pack-msix.ps1's layout (one assembly, three artifacts), signs the four exes individually, emits setup.exe + a portable zip. Same signing backends and fail-closed-on-tags rule as the sibling scripts; no .cer (an exe runs untrusted). - windows-client.yml: pack step after the MSIX, publish + release-attach the new artifacts (canary/latest aliases punktfunk-client-setup_<arch>.exe, ..._<arch>-portable.zip). - deeplink.rs: write_shortcut targets the app-execution alias only under package identity; unpackaged installs have no alias but a stable path, so they target current_exe(). has_package_identity() now shared with main.rs's AppUserModelID probe. - docs: install-client (installer default + a 'Launching through Steam' section + MSIX/portable as alternates), channels, uninstall, clients, platforms.json (both copies, drift check green).enricobuehler referenced this pull request2026-08-19 23:24:48 +00:00