Service owns its binaries + is stoppable without admin; installer offers the service
The service was registered to run from wherever it was installed FROM (Environment .ProcessPath), so installing from a dev/test folder pinned it there: it locked those files (blocking every rebuild) and, for a real user installing from the app folder, would lock the app's own binaries and break the auto-updater. Stopping it also needed admin, so only the app's UAC-prompting Service menu could do it. Fixes: - The service now installs its OWN copy of the program into ProgramData\RemSound\ service\bin and is registered to run from there. Never touches the install/dev folder again. CopyProgramTo copies the exe + DLLs + runtimes + default sounds but excludes user-state folders; uninstall removes the bin copy. - Install grants Authenticated Users start/stop/query on the service (sc sdset, ACE merged into the existing DACL) so it can be stopped with a plain `sc stop RemSoundService` or the Service menu -- no admin, no app. Pure SDDL-amend helper is unit-tested (placement + idempotency). - The app installer now asks, after install, whether to also install the service (optional, its own UAC step; declining is fine -- Service menu installs it later). - deploy-test.ps1: only a copy running FROM the publish folder locks its binaries, so only that forces a sounds-only deploy. The service (ProgramData) and an installed app no longer make the script silently skip the binary publish -- the bug that had us testing stale builds for rounds. New self-test "Service self-contained install" (runs-from-own-bin, SDDL amend, copy exclusions). Gate: 40/40. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a450cae66a
commit
4e15451e1d
+11
-2
@@ -33,9 +33,18 @@ function Invoke-Robocopy([string[]]$rcArgs) {
|
||||
if ($LASTEXITCODE -ge 8) { throw "robocopy failed ($LASTEXITCODE): $($rcArgs -join ' ')" }
|
||||
}
|
||||
|
||||
$soundOnly = @(Get-Process RemSound -ErrorAction SilentlyContinue).Count -gt 0
|
||||
# Only a RemSound process running FROM the publish folder locks its binaries. The send-only Windows
|
||||
# service runs from its own copy under ProgramData (...\service\bin) and an installed app runs from
|
||||
# %LocalAppData%\Programs\RemSound - neither locks publish, so neither should force a sounds-only deploy.
|
||||
# (This is the bug that silently skipped binary deploys while the service was running - 2026-07-17.)
|
||||
$publishFull = (Resolve-Path -LiteralPath $publish -ErrorAction SilentlyContinue).Path
|
||||
$locking = @(Get-Process RemSound -ErrorAction SilentlyContinue | Where-Object {
|
||||
try { $_.Path -and $publishFull -and $_.Path.StartsWith($publishFull, [System.StringComparison]::OrdinalIgnoreCase) }
|
||||
catch { $false } # .Path throws for the SYSTEM service (access denied) - it's not in publish, so ignore it
|
||||
})
|
||||
$soundOnly = $locking.Count -gt 0
|
||||
if ($soundOnly) {
|
||||
Write-Host "RemSound is running - refreshing SOUNDS only (binaries are locked; close RemSound to update them)." -ForegroundColor Yellow
|
||||
Write-Host "A RemSound is running FROM the publish folder - refreshing SOUNDS only (its binaries are locked; close that copy to update them)." -ForegroundColor Yellow
|
||||
}
|
||||
else {
|
||||
# Never deploy a build to test that hasn't passed the tests. The gate publishes + tests its own
|
||||
|
||||
Reference in New Issue
Block a user