# Windows service (deployment) The `PunktfunkHost` Windows service is the end-user way to run the host on Windows. It replaces the manual bring-up chain (a scheduled task → `PsExec64 -s -i 1` → `wscript launch.vbs` → `host-run.cmd`) with one command, auto-start on boot, and supervision. ## Install (installer — recommended) Download the signed installer from the package registry (`punktfunk-host-windows`, ) and run it (it elevates itself): ``` punktfunk-host-setup-.exe # wizard punktfunk-host-setup-.exe /VERYSILENT # unattended ``` It lays the host into `C:\Program Files\punktfunk`, optionally installs the bundled **SudoVDA** virtual-display driver, then runs `service install` + `service start` for you. Upgrades stop the service first and re-point it; uninstall (Add/Remove Programs) runs `service uninstall`. Packaging details: [`packaging/windows/README.md`](../packaging/windows/README.md). A self-signed CI build also publishes a `.cer` — import it once (`Import-Certificate -FilePath punktfunk-host-windows.cer -CertStoreLocation Cert:\LocalMachine\TrustedPublisher`) so Windows trusts the signed setup. ## Install (manual / CLI) From an **elevated** (Administrator) prompt: ```powershell punktfunk-host service install # register auto-start LocalSystem service + firewall rules + default host.env punktfunk-host service start # start it now (also starts automatically on every boot) ``` `service install` is idempotent — run it again after upgrading the exe to re-point the service at the new binary. Register whatever location you keep the exe in (e.g. `C:\Program Files\punktfunk\`); the service records the current exe path. Other subcommands: ```powershell punktfunk-host service stop punktfunk-host service status punktfunk-host service uninstall # stop + delete the service + remove its firewall rules ``` ## How it works The host must run **as SYSTEM in the interactive session** (Session 1+): Desktop Duplication of the secure desktop (UAC / lock / login) and `SendInput` need SYSTEM, and capture/injection need the interactive session, which a plain Session-0 service is not in. So the service (itself in Session 0) **never captures**. On start, and whenever the active console session changes, it: 1. resolves the active console session (`WTSGetActiveConsoleSessionId`), 2. duplicates its own LocalSystem token and retargets it to that session (`SetTokenInformation` `TokenSessionId`), 3. launches the host there with `CreateProcessAsUserW` (`lpDesktop = winsta0\default`), 4. supervises it: relaunches on exit/crash (with backoff) and on a console connect/disconnect. A kill-on-close **job object** ensures a service crash never orphans the SYSTEM host. The host in turn spawns the WGC helper into the *user* session (see [`windows-secure-desktop.md`](windows-secure-desktop.md)) — two nested launches. Lock/unlock are handled inside the host (the `DesktopWatcher` DDA↔WGC mux), so the service deliberately does **not** relaunch on lock/unlock — only on a real session switch. This is the same model Sunshine/Apollo use. ## Configuration Config lives in **`%ProgramData%\punktfunk\host.env`** (KEY=VALUE lines, `#` comments). `service install` writes a default if none exists. Template: [`scripts/windows/host.env.example`](../scripts/windows/host.env.example). ```ini PUNKTFUNK_ENCODER=nvenc PUNKTFUNK_VIDEO_SOURCE=virtual PUNKTFUNK_SECURE_DDA=1 RUST_LOG=info # PUNKTFUNK_HOST_CMD=serve --native # the host subcommand the service launches (default) ``` The service loads these into its environment and carries `PUNKTFUNK_*` + `RUST_LOG` to the host child (the same env-merge the WGC helper uses). Restart the service after editing: ```powershell punktfunk-host service stop; punktfunk-host service start ``` The host's identity (cert/pairing/mgmt token/library) also lives under `%ProgramData%\punktfunk` — a machine-wide dir the SYSTEM service and the interactive user share, surviving user logout. `PUNKTFUNK_CONFIG_DIR` overrides the location (both platforms; handy for tests). ## Logs - `%ProgramData%\punktfunk\logs\service.log` — the service's own supervision log (spawn/exit/session switches). - `%ProgramData%\punktfunk\logs\host.log` — the host child's stdout/stderr. ## Prerequisites - The host built with `--features nvenc` for NVENC (the driver ships `nvEncodeAPI64.dll`; no SDK needed at runtime). Software encode otherwise. - The **SudoVDA** indirect display driver installed (for `PUNKTFUNK_VIDEO_SOURCE=virtual`). - **ViGEmBus** for virtual gamepads (optional). ## Gotchas - `service install`/`uninstall` need an **elevated** prompt (the SCM rejects non-admin). - `service run` is the SCM entry point — don't run it by hand (it errors with a hint). - A **graceful** stop currently `TerminateProcess`es the host, so its RAII teardown (SudoVDA monitor REMOVE) doesn't run; a stale virtual monitor can linger until the next start. A cooperative-stop signal is a follow-up.