Service: offer to start it right after installing (uninstall already stops first)
- After a successful install, both entry points now ask "start it now?" (Yes/No): the app's Service menu (RunServiceVerbAsync reused for the follow-up start) and the app installer's optional service step. Without this the service only comes up at the next boot, so a first-time user saw nothing happen after installing it. - Uninstall already stops the service before deleting (DoUninstall -> DoStop, which waits up to 15s for Stopped), so nothing to change there - confirmed, not added. - Manual: note the start-now prompt in the service section. No new automated test: these are UI Yes/No prompts layered on the already-tested start/stop verbs. Gate 46/46. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
aa5707f8e1
commit
0102aa51f4
+1
-1
@@ -1412,7 +1412,7 @@ RemSound.exe --connect 192.168.1.42
|
||||
<p>Everything lives in the <strong>Service</strong> menu on the menu bar:</p>
|
||||
<ol>
|
||||
<li><strong>Configure service profile…</strong> — opens a small window with two tabs (Connectivity and Audio send) where you choose who to send to (plus a password) and what to send. On the Audio send tab, the first output choice is <strong>Use Windows default audio device, follows Windows changes</strong> — tick that to send whatever this machine is currently playing and keep following the Windows default if it later changes, rather than pinning one named card. (You can still pick specific devices, or a specific application, exactly as in the normal app.) There is no “send my audio” switch because the service always sends, and there is no audio-quality tab to fiddle with: the service always uses the settings that work best for live streaming (the Opus live-latency codec, small packets, locked to the audio clock), so it just sounds right. This is a separate profile from your normal ones and does not appear in the usual profile list. The <strong>Additional options</strong> button lets you turn the connect/disconnect sounds and the service's own log on or off.</li>
|
||||
<li><strong>Install service</strong> — registers it with Windows so it starts automatically at every boot. Windows asks for administrator permission (one prompt). Do this once. (When you first install RemSound on a PC, the installer also offers to set the service up for you, so you may have done this already.)</li>
|
||||
<li><strong>Install service</strong> — registers it with Windows so it starts automatically at every boot. Windows asks for administrator permission (one prompt). Do this once. Straight after installing, RemSound asks whether you'd like to <strong>start it now</strong> (otherwise it waits until the next reboot). (When you first install RemSound on a PC, the app installer also offers to set the service up — and start it — for you, so you may have done this already.)</li>
|
||||
<li><strong>Start service</strong> / <strong>Stop service</strong> — run or halt it now without waiting for a reboot.</li>
|
||||
<li><strong>Uninstall service</strong> — removes it entirely.</li>
|
||||
</ol>
|
||||
|
||||
@@ -187,11 +187,32 @@ internal static class AppInstaller
|
||||
{
|
||||
log?.Invoke("install: user opted to install the service too");
|
||||
var rc = ServiceControl.RunElevated(ServiceControl.InstallVerb);
|
||||
MessageBox.Show(owner,
|
||||
rc == 0
|
||||
? "The RemSound service was installed. Configure and start it from the app's Service menu when you want it running."
|
||||
: "The RemSound service was not installed (the elevation prompt was declined, or it failed). You can try again later from the app's Service menu.",
|
||||
"RemSound service", MessageBoxButtons.OK, rc == 0 ? MessageBoxIcon.Information : MessageBoxIcon.Warning);
|
||||
if (rc == 0)
|
||||
{
|
||||
// Offer to start it now — otherwise it only comes up at the next boot, so a
|
||||
// first-time user sees nothing happen after installing it.
|
||||
var startNow = MessageBox.Show(owner,
|
||||
"The RemSound service was installed." + Environment.NewLine + Environment.NewLine +
|
||||
"Do you want to start it now? It will also start automatically at every boot. " +
|
||||
"You can configure who it sends to from the app's Service menu.",
|
||||
"Start the RemSound service?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
if (startNow == DialogResult.Yes)
|
||||
{
|
||||
log?.Invoke("install: user opted to start the service now");
|
||||
var startRc = ServiceControl.RunElevated(ServiceControl.StartVerb);
|
||||
MessageBox.Show(owner,
|
||||
startRc == 0
|
||||
? "The RemSound service is running."
|
||||
: "The service was installed but couldn't be started just now. You can start it later from the app's Service menu.",
|
||||
"RemSound service", MessageBoxButtons.OK, startRc == 0 ? MessageBoxIcon.Information : MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(owner,
|
||||
"The RemSound service was not installed (the elevation prompt was declined, or it failed). You can try again later from the app's Service menu.",
|
||||
"RemSound service", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2378,12 +2378,17 @@ public sealed class MainForm : Form
|
||||
: "Uninstall the RemSound service?\n\nWindows will ask for administrator permission.";
|
||||
if (MessageBox.Show(this, msg, AppName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
|
||||
}
|
||||
RunServiceVerbAsync(verb, label);
|
||||
}
|
||||
|
||||
/// <summary>Run an elevated service verb OFF the UI thread and report the outcome on it. A slow or
|
||||
/// stuck helper must never freeze the window or its audio — that was the install hang: the UI thread
|
||||
/// sat in WaitForExit while the pipe-deadlocked installer never returned, so the app locked up and
|
||||
/// streaming died. The UI stays live; we report when the helper comes back or the wait times out.</summary>
|
||||
private void RunServiceVerbAsync(string verb, string label)
|
||||
{
|
||||
logFile.Event($"service: {label} requested (elevated)");
|
||||
ServiceStore.AppendServiceEvent($"{label} requested (elevated)");
|
||||
// Run the elevated helper OFF the UI thread. A slow or stuck helper must never freeze the window or
|
||||
// its audio — that was the install hang: the UI thread sat in WaitForExit while the pipe-deadlocked
|
||||
// installer never returned, so the app locked up and streaming died. The UI stays live; we report
|
||||
// the outcome (on the UI thread) when the helper comes back or the wait times out.
|
||||
Task.Run(() =>
|
||||
{
|
||||
var rc = ServiceControl.RunElevated(verb);
|
||||
@@ -2401,7 +2406,19 @@ public sealed class MainForm : Form
|
||||
logFile.Event($"service: {label} finished with code {rc} ({outcome})");
|
||||
ServiceStore.AppendServiceEvent($"{label} finished: code {rc} ({outcome})");
|
||||
if (rc == 0)
|
||||
{
|
||||
// After a successful install, offer to start it now — it otherwise only starts at the next
|
||||
// boot, so a first-time user would see nothing happen.
|
||||
if (label == "install")
|
||||
{
|
||||
var startNow = MessageBox.Show(this,
|
||||
"The RemSound service was installed. Do you want to start it now?\n\nIt will also start automatically at every boot.",
|
||||
AppName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
if (startNow == DialogResult.Yes) RunServiceVerbAsync(ServiceControl.StartVerb, "start");
|
||||
return;
|
||||
}
|
||||
MessageBox.Show(this, $"Service {label} succeeded.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else if (rc == -1)
|
||||
MessageBox.Show(this, $"Service {label} was cancelled, or administrator rights were declined.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
else if (rc == ServiceControl.ElevatedTimedOut)
|
||||
|
||||
Reference in New Issue
Block a user