Skip to content

[Code Quality] ServiceManager — MapStartupType returns Manual for ServiceStartMode.Boot/System but GetServiceStartupType returns null (silent data drift in batch list) #1042

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity

Warning (Correctness — silent data corruption in service enumeration)

Location

src/Servy.Core/Services/ServiceManager.cs

  • MapStartupType (lines 1058-1085) — used by GetAllServices (batch)
  • GetServiceStartupType (lines 778-848) — used for single-service queries

Code

```csharp
// MapStartupType (line 1062, default branch line 1067) - used by GetAllServices
switch (service.StartType)
{
case ServiceStartMode.Automatic: return ServiceStartType.Automatic;
case ServiceStartMode.Manual: return ServiceStartType.Manual;
case ServiceStartMode.Disabled: return ServiceStartType.Disabled;
default: return ServiceStartType.Manual; // <-- 'Boot' and 'System' fall through here
}

// GetServiceStartupType (line 792, default branch line 797) - single-service query
switch (sc.StartType)
{
case ServiceStartMode.Automatic: startupType = ServiceStartType.Automatic; break;
case ServiceStartMode.Manual: startupType = ServiceStartType.Manual; break;
case ServiceStartMode.Disabled: startupType = ServiceStartType.Disabled; break;
default: return null; // <-- 'Boot' and 'System' fall through here
}
```

Explanation

System.ServiceProcess.ServiceControllerStatus / ServiceStartMode has five members: Boot, System, Automatic, Manual, Disabled. Boot and System are used by device drivers and a small set of system-level services that load before/with the kernel.

The two methods above map the same .NET enum but disagree on the unmapped values:

  • MapStartupType reports them as Manual — a concrete, wrong value that flows into the UI and any reports built from GetAllServices.
  • GetServiceStartupType reports them as null — the truthful "unknown" answer.

A user listing all services in the Manager will see Boot/System driver-like services as Manual, then if they click into a single service the detail view (which goes through GetServiceStartupType) will show Unknown / N/A. The two views disagree about the same row in the same machine state.

Suggested fix

Standardize on the truthful answer. Add an Unknown member to ServiceStartType (it already has Unknown per line 846) and have both methods return it for unmapped enum values:

```csharp
// In MapStartupType:
default: return ServiceStartType.Unknown;
```

This keeps the two paths in agreement and stops silently mislabelling Boot/System services as Manual in the list view.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions