Service: config dialog + Service menu
Local checkpoint - NOT for public release.
- ServiceProfileDialog: modal 3-tab editor (Audio send / Audio profile / Connectivity)
reusing the house controls, with a Save and Close / Cancel / Additional options
button row. Send-only: send-mode chooser + WASAPI outputs/apps + inputs (no "Send
my audio" toggle, no receive, no ASIO); codec/rate/lock-to-clock; peers add/remove +
a Set password button. Additional options sub-dialog = play connect/disconnect sound
+ enable service logging. Edits a Profile clone; returns it on OK.
- Service menu in MainForm: status line + Configure / Install / Uninstall / Start / Stop,
items enabled per live state on drop-down. Install/uninstall confirm then elevate.
Configure saves the reserved service profile, points AppConfig at it, stores the
machine-wide logging choice, and restarts a running service to pick up edits.
- ProfileStore.ReservedServiceProfileTitle ("RemSound service"): the service profile
lives with normal profiles (so the service Loads it) but ListProfileTitles hides it
from every picker. ServiceControl reuses that single constant.
- Self-test: the service dialog is now in the accessibility audit (constructs cleanly,
unique mnemonics, all controls named). Gate 20/20.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5dbbe4dd71
commit
f4551517e5
@@ -49,9 +49,14 @@ public sealed class ProfileStore
|
||||
/// <summary>Folder this store reads from and writes into.</summary>
|
||||
public string BaseDirectory => baseDir;
|
||||
|
||||
/// <summary>Reserved title of the send-only Windows service's profile. It lives in the same folder
|
||||
/// as normal profiles (so the service loads it via <see cref="Load"/>), but it's edited only through
|
||||
/// the Service menu's config dialog and hidden from the normal picker by <see cref="ListProfileTitles"/>.</summary>
|
||||
public const string ReservedServiceProfileTitle = "RemSound service";
|
||||
|
||||
/// <summary>Returns the user-facing titles of every profile in the folder, sorted
|
||||
/// alphabetically (case-insensitive). Excludes the synthetic blank-template; the
|
||||
/// caller decides whether to surface that.</summary>
|
||||
/// alphabetically (case-insensitive). Excludes the synthetic blank-template and the reserved
|
||||
/// service profile; the caller decides whether to surface the blank template.</summary>
|
||||
public IReadOnlyList<string> ListProfileTitles()
|
||||
{
|
||||
if (!Directory.Exists(baseDir)) return [];
|
||||
@@ -60,6 +65,7 @@ public sealed class ProfileStore
|
||||
return Directory.GetFiles(baseDir, "*.json")
|
||||
.Select(p => TryReadTitle(p) ?? Path.GetFileNameWithoutExtension(p))
|
||||
.Where(static t => !string.IsNullOrWhiteSpace(t))
|
||||
.Where(static t => !string.Equals(t, ReservedServiceProfileTitle, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(t => t, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user