Restore Win7 launch safety: version-gate the Service menu, don't probe
The capability PROBE (added earlier for feature-detect) constructed a ServiceController during window construction, which loaded System.ServiceProcess on EVERY launch. On Win11 that's harmless, but on Win7 it meant the app was attempting that risky load at startup, surviving only on a catch — too fragile for a guarantee. Verified empirically: a normal launch was loading System.ServiceProcess.ServiceController.dll again. Fix: decide Service-menu visibility with a Windows-VERSION check (OperatingSystem.IsWindowsVersionAtLeast(10,0)) instead of a runtime probe. A version check touches no service type, so the service assembly is NOT referenced at launch on any OS. On Win7/8 the menu is hidden and that assembly is never loaded; on Win10+ it loads only later, if the user actually opens the Service menu (already wrapped in try/catch). Feature-detecting on Win7 and keeping Win7 launch-safe are mutually exclusive (you can't test the load without doing it), so we choose guaranteed launch safety. - Deleted ServiceCapability (the probe) — now unused. - Replaced its self-test with "Main window builds without loading the service assembly (Win7-safe)": constructing the main window must not load System.ServiceProcess. Verified empirically too: normal launch now loads 0 service modules (was 1). Gate 33/33. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
541f66d379
commit
0567ea22c3
@@ -2182,14 +2182,16 @@ public sealed class MainForm : Form
|
||||
// and the arrow keys.
|
||||
menu.Items.Add(fileMenu);
|
||||
menu.Items.Add(recordMenu);
|
||||
// Offer the Service menu wherever the send-only service can actually run — feature-detected, not
|
||||
// gated on a Windows version, so it appears on Windows 7 too if the .NET service layer loads there
|
||||
// (Ed's ask: install on "Win7 or above" wherever it's supported). ServiceCapability probes safely:
|
||||
// if System.ServiceProcess can't load on this OS, it catches that and the menu is simply hidden, so
|
||||
// an older Windows can never be crashed by it. The startup path is already service-type-free via
|
||||
// ServiceEntry, so this probe (at window construction, never at launch) is the only place that
|
||||
// decides visibility.
|
||||
if (ServiceCapability.IsAvailable())
|
||||
// Offer the Service menu on Windows 10+ only. This is a VERSION check on purpose, not a runtime
|
||||
// probe: a probe would have to construct a ServiceController to test it, which loads
|
||||
// System.ServiceProcess — the exact assembly that won't load on Windows 7 — during window
|
||||
// construction on EVERY launch. Deciding by version is free (it touches no service type), so on
|
||||
// Windows 7/8 the menu is simply hidden and that assembly is never referenced at launch at all,
|
||||
// which is what keeps the app launching there. On Windows 10+ the assembly loads only later, if the
|
||||
// user actually opens the Service menu (the DropDownOpening handler, wrapped in try/catch). Feature-
|
||||
// detecting on Win7 and keeping Win7 launch-safe are mutually exclusive — you can't test whether the
|
||||
// assembly loads without loading it — so we choose guaranteed launch safety.
|
||||
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0))
|
||||
menu.Items.Add(BuildServiceMenu());
|
||||
menu.Items.Add(optionsMenu);
|
||||
menu.Items.Add(helpMenu);
|
||||
|
||||
Reference in New Issue
Block a user