refactor(host/windows): clean up DDA path + add a proper Windows service

Final cleanup after the DDA-parity work, plus an end-user service to replace the
PsExec/VBS/scheduled-task launch chain.

Cleanup (behavior-preserving):
- sudovda.rs: drop the dead legacy GDI isolate_displays/restore_displays (CCD is
  the sole isolation path), the always-empty Monitor.isolated field, and the
  vestigial reassert_isolation + PUNKTFUNK_ISOLATE_DISPLAYS knob; fix stale comments.
- dxgi.rs: downgrade leftover debug warns/infos (DuplicateOutput1 retry, FALLBACKS,
  hook-hits, AcquireNextFrame idle timeout) to debug!; remove the PUNKTFUNK_NO_CURSOR
  per-frame test knob.

Windows service (src/service.rs, `punktfunk-host service`):
- SCM supervisor (windows-service crate) that duplicates its LocalSystem token,
  retargets it to the active console session, and CreateProcessAsUserW's the host
  there (Sunshine/Apollo model) — relaunching on exit and console session switch,
  inside a kill-on-close job object so a service crash never orphans the host.
- install/uninstall/start/stop/status subcommands: one elevated `service install`
  registers an auto-start LocalSystem service + firewall rules + a default host.env.
- Config moves to %ProgramData%\punktfunk\host.env; config_dir() now resolves to
  %ProgramData%\punktfunk on Windows (replacing the APPDATA=C:\Users\Public hack),
  with a PUNKTFUNK_CONFIG_DIR override. Logs land in %ProgramData%\punktfunk\logs\.
- merged_env_block (shared with the WGC helper) now also carries RUST_LOG.
- docs/windows-service.md + scripts/windows/host.env.example; windows-host.md updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 18:33:53 +00:00
parent 6d611cf889
commit 0ce2e37faf
11 changed files with 1020 additions and 201 deletions
+36
View File
@@ -0,0 +1,36 @@
# punktfunk host configuration (Windows) — read by the `PunktfunkHost` service.
#
# `punktfunk-host service install` writes a default copy of this to
# %ProgramData%\punktfunk\host.env
# Edit that file (not this one) and restart the service to apply:
# punktfunk-host service stop
# punktfunk-host service start
#
# Format: KEY=VALUE per line; '#' starts a comment. The service loads these into its environment
# and passes PUNKTFUNK_* and RUST_LOG through to the host it launches into the active session.
# Hardware encode via NVENC (NVIDIA). The host must be the `--features nvenc` build. Falls back to
# the software encoder automatically if NVENC is unavailable.
PUNKTFUNK_ENCODER=nvenc
# Video source: `virtual` creates a per-client virtual display (SudoVDA) at the client's exact
# resolution + refresh — the flagship mode. Requires the SudoVDA indirect display driver installed.
PUNKTFUNK_VIDEO_SOURCE=virtual
# Capture the secure desktop (UAC / lock / login) so the stream survives those transitions.
PUNKTFUNK_SECURE_DDA=1
# Log level (info | debug | trace). Logs land in %ProgramData%\punktfunk\logs\.
RUST_LOG=info
# The host subcommand the service launches. Default: `serve --native` (GameStream/Moonlight + the
# native punktfunk/1 QUIC host in one process). Uncomment to override.
#PUNKTFUNK_HOST_CMD=serve --native
# Multi-GPU boxes only: force the NVENC/Desktop-Duplication GPU by Description substring. Leave
# unset on single-GPU machines (the default auto-picks the discrete adapter).
#PUNKTFUNK_RENDER_ADAPTER=4090
# Keep a per-client virtual display alive briefly after disconnect so a quick reconnect reuses it
# (no display connect/disconnect chime). Default 10000 ms.
#PUNKTFUNK_MONITOR_LINGER_MS=10000