fix(installer/windows): only a host that will actually RUN is a conflict
docker / deploy-docs (push) Successful in 41s
ci / web (push) Successful in 56s
ci / docs-site (push) Successful in 1m50s
apple / swift (push) Successful in 5m41s
ci / bench (push) Successful in 7m1s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 2m3s
ci / rust-arm64 (push) Successful in 9m51s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 27s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 27s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 30s
deb / build-publish-host (push) Successful in 11m32s
deb / build-publish-client-arm64 (push) Successful in 10m59s
decky / build-publish (push) Successful in 41s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 30s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 6m19s
android / android (push) Successful in 17m31s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Failing after 5m35s
windows-host / package (push) Successful in 11m21s
windows-host / winget-source (push) Skipped
arch / build-publish (push) Successful in 19m9s
docker / build-push-arm64cross (push) Successful in 5m7s
ci / rust (push) Successful in 22m25s
deb / build-publish (push) Successful in 10m49s
apple / screenshots (push) Successful in 23m8s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 21m34s
docker / deploy-docs (push) Successful in 41s
ci / web (push) Successful in 56s
ci / docs-site (push) Successful in 1m50s
apple / swift (push) Successful in 5m41s
ci / bench (push) Successful in 7m1s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 2m3s
ci / rust-arm64 (push) Successful in 9m51s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 27s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 27s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 30s
deb / build-publish-host (push) Successful in 11m32s
deb / build-publish-client-arm64 (push) Successful in 10m59s
decky / build-publish (push) Successful in 41s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 30s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 6m19s
android / android (push) Successful in 17m31s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Failing after 5m35s
windows-host / package (push) Successful in 11m21s
windows-host / winget-source (push) Skipped
arch / build-publish (push) Successful in 19m9s
docker / build-push-arm64cross (push) Successful in 5m7s
ci / rust (push) Successful in 22m25s
deb / build-publish (push) Successful in 10m49s
apple / screenshots (push) Successful in 23m8s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 21m34s
Field report within hours of 0.20.0 (HitFrostbite): `winget install unom.PunktfunkHost` fails with "Installer failed with exit code: 1", 0x8A150006, after the hash verifies and the install starts. That is Setup aborting on purpose. `StreamHostPresent` counted a conflicting host as present if its SCM service key existed at ANY start type, OR if a bare Program Files\<Name> directory existed — so a disabled service, or a folder left behind by an uninstall, read as a live conflict.3d893013then made the warning a SuppressibleMsgBox defaulting to IDNO so unattended installs could not hang on it; under winget's /VERYSILENT /SUPPRESSMSGBOXES that default aborts InitializeSetup, and Inno exits "failed to initialize" = code 1. Net effect: anyone with Sunshine on disk — the exact audience most likely to migrate — could not install via winget at all, with no visible reason. The other candidate for exit 1 is excluded rather than assumed: the manifest declares MinimumOSVersion 10.0.22621.0 matching the script's MinVersion, so winget refuses an unsupported OS BEFORE downloading, and the report shows the hash verified and the install starting. The conflict check is also the only `Result := False` in InitializeSetup. Detection now keys on the service's `Start` value (0 boot / 1 system / 2 automatic / 3 manual / 4 disabled), counting only 0-2 — a host that comes up on its own is the only kind that can take the GameStream ports or load a second virtual-display driver. Directories no longer count at all: they were the noisiest signal and the one that survives an uninstall. This makes the installer agree with the tray, which dropped its always-on warning over a merely-INSTALLED Sunshine in this same release (3e782852) for exactly the same reason. The message now says "installed and set to start automatically" and offers disabling the service as a remedy, both of which are what is actually detected. A conflicting host running as a plain user process is deliberately not detected: pure Pascal cannot enumerate processes, it is a runtime rather than install-time condition, and the host already reports it via the `punktfunk::detect` startup warning, `detect-conflicts`, and /api/v1/local/summary. Verified by compiling the [Code] section with ISCC 6.7.1 on the windows-amd64 runner (WithWeb defined, as CI does). That caught two defects in my own first draft that review would not have: a continuation line STARTING with #13#10, which ISPP reads as a preprocessor directive ("Unknown preprocessor directive", compile aborted), and `{commonpf}` written inside a `{ }` comment, which closes it early since Inno comments do not nest. Both are noted at the sites so they are not reintroduced.
This commit is contained in:
@@ -354,15 +354,31 @@ begin
|
|||||||
Result := ExpandConstant('{commonappdata}\punktfunk\host.env');
|
Result := ExpandConstant('{commonappdata}\punktfunk\host.env');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ True if another Moonlight-compatible streaming host is installed - by its SCM service key or its
|
{ True if another Moonlight-compatible streaming host is not merely present but will actually RUN.
|
||||||
Program Files directory. Sunshine and its forks all register a "<Name>Service" and install under
|
Sunshine and its forks register a "<Name>Service"; `Start` is that service's start type
|
||||||
Program Files, so a registry + directory probe catches them without enumerating processes (which
|
(REG_DWORD): 0 boot, 1 system, 2 automatic, 3 manual, 4 disabled. Only 0-2 come up on their own,
|
||||||
pure Pascal can't do cleanly). }
|
and only a host that comes up can take the GameStream ports or load a second virtual-display
|
||||||
function StreamHostPresent(SvcKey, DirName: String): Boolean;
|
driver - which is the entire content of the warning below.
|
||||||
|
|
||||||
|
DELIBERATELY NARROWER than it was. The old probe also counted the service key existing at ANY
|
||||||
|
start type, plus a bare Program Files\<Name> directory - so a disabled service, or a leftover folder
|
||||||
|
from an uninstall, read as a live conflict. Combined with the silent-install default of IDNO that
|
||||||
|
aborted setup, and a field report followed within hours of 0.20.0: `winget install
|
||||||
|
unom.PunktfunkHost` failed with exit code 1 (0x8A150006) on a box whose Sunshine was not running.
|
||||||
|
Nothing about a dormant install can clash, and the tray reached the same conclusion in this same
|
||||||
|
release (3e782852 dropped its always-on warning over a merely-INSTALLED Sunshine as a false
|
||||||
|
alarm) - the two surfaces now agree.
|
||||||
|
|
||||||
|
A host running as a plain user process rather than a service is not detected here, by choice:
|
||||||
|
that cannot be seen from pure Pascal, it is a runtime condition rather than an install-time one,
|
||||||
|
and the host already reports it where it belongs (the `punktfunk::detect` startup warning, the
|
||||||
|
`detect-conflicts` subcommand, and /api/v1/local/summary). }
|
||||||
|
function StreamHostEnabled(SvcKey: String): Boolean;
|
||||||
|
var
|
||||||
|
StartType: Cardinal;
|
||||||
begin
|
begin
|
||||||
Result := RegKeyExists(HKLM, 'SYSTEM\CurrentControlSet\Services\' + SvcKey)
|
Result := RegQueryDWordValue(HKLM, 'SYSTEM\CurrentControlSet\Services\' + SvcKey, 'Start', StartType)
|
||||||
or DirExists(ExpandConstant('{commonpf}\' + DirName))
|
and (StartType <= 2);
|
||||||
or DirExists(ExpandConstant('{commonpf32}\' + DirName));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Runs before any wizard page - the earliest point we can warn. Detect a conflicting host and let
|
{ Runs before any wizard page - the earliest point we can warn. Detect a conflicting host and let
|
||||||
@@ -375,11 +391,11 @@ begin
|
|||||||
{ Record the fresh-vs-upgrade verdict while host.env still reflects the PREVIOUS run. }
|
{ Record the fresh-vs-upgrade verdict while host.env still reflects the PREVIOUS run. }
|
||||||
FreshHostInstall := not FileExists(HostEnvPath);
|
FreshHostInstall := not FileExists(HostEnvPath);
|
||||||
Found := '';
|
Found := '';
|
||||||
if StreamHostPresent('SunshineService', 'Sunshine') then Found := Found + ' - Sunshine' + #13#10;
|
if StreamHostEnabled('SunshineService') then Found := Found + ' - Sunshine' + #13#10;
|
||||||
if StreamHostPresent('ApolloService', 'Apollo') then Found := Found + ' - Apollo' + #13#10;
|
if StreamHostEnabled('ApolloService') then Found := Found + ' - Apollo' + #13#10;
|
||||||
if StreamHostPresent('VibeshineService', 'Vibeshine') then Found := Found + ' - Vibeshine' + #13#10;
|
if StreamHostEnabled('VibeshineService') then Found := Found + ' - Vibeshine' + #13#10;
|
||||||
if StreamHostPresent('VibepolloService', 'Vibepollo') then Found := Found + ' - Vibepollo' + #13#10;
|
if StreamHostEnabled('VibepolloService') then Found := Found + ' - Vibepollo' + #13#10;
|
||||||
if StreamHostPresent('LuminalShineService', 'LuminalShine') then Found := Found + ' - LuminalShine' + #13#10;
|
if StreamHostEnabled('LuminalShineService') then Found := Found + ' - LuminalShine' + #13#10;
|
||||||
if Found <> '' then
|
if Found <> '' then
|
||||||
{ SuppressibleMsgBox, NOT MsgBox: a plain MsgBox ignores /SUPPRESSMSGBOXES and displays even
|
{ SuppressibleMsgBox, NOT MsgBox: a plain MsgBox ignores /SUPPRESSMSGBOXES and displays even
|
||||||
under /VERYSILENT - i.e. an unattended install (winget) would block on a modal dialog with no
|
under /VERYSILENT - i.e. an unattended install (winget) would block on a modal dialog with no
|
||||||
@@ -387,12 +403,15 @@ begin
|
|||||||
install onto a box that already runs Sunshine/Apollo ABORTS (Setup exits non-zero) instead of
|
install onto a box that already runs Sunshine/Apollo ABORTS (Setup exits non-zero) instead of
|
||||||
proceeding into the unsupported dual-host state the message describes. }
|
proceeding into the unsupported dual-host state the message describes. }
|
||||||
Result := SuppressibleMsgBox(
|
Result := SuppressibleMsgBox(
|
||||||
'Another game-streaming host is already installed on this PC:' + #13#10#13#10 + Found + #13#10 +
|
{ NB: keep #13#10 off the START of a line - ISPP reads a leading '#' as a preprocessor
|
||||||
|
directive and aborts the compile with "Unknown preprocessor directive". }
|
||||||
|
'Another game-streaming host is installed on this PC and set to start automatically:' + #13#10#13#10 + Found + #13#10 +
|
||||||
'Running Punktfunk alongside Sunshine / Apollo / other Moonlight-compatible hosts is NOT ' +
|
'Running Punktfunk alongside Sunshine / Apollo / other Moonlight-compatible hosts is NOT ' +
|
||||||
'supported. They bind the same GameStream network ports (47984, 47989, 47998-48010) and ' +
|
'supported. They bind the same GameStream network ports (47984, 47989, 47998-48010) and ' +
|
||||||
'install a conflicting virtual-display driver, which causes pairing failures, "address ' +
|
'install a conflicting virtual-display driver, which causes pairing failures, "address ' +
|
||||||
'already in use" errors and capture glitches.' + #13#10#13#10 +
|
'already in use" errors and capture glitches.' + #13#10#13#10 +
|
||||||
'Stop and uninstall the other host before using Punktfunk.' + #13#10#13#10 +
|
'Stop and disable its service (or uninstall it) before using Punktfunk. A host that is ' +
|
||||||
|
'installed but disabled does not clash and is not reported here.' + #13#10#13#10 +
|
||||||
'Continue with the installation anyway?',
|
'Continue with the installation anyway?',
|
||||||
mbConfirmation, MB_YESNO or MB_DEFBUTTON2, IDNO) = IDYES;
|
mbConfirmation, MB_YESNO or MB_DEFBUTTON2, IDNO) = IDYES;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user