A developer-friendly .NET library for managing Windows services programmatically.
- Install/Update - Create new services or update existing service configurations
- Start/Stop/Restart - Control service lifecycle with timeout support
- Status Query - Check service state and retrieve service information
- Uninstall - Remove services safely
- Idempotent - Operations handle already-running/stopped services gracefully
- Non-throwing queries -
TryGetAsyncreturnsnullinstead of throwing exceptions - Multi-targeted - Supports .NET 8+, .NET 9+, .NET 10+
dotnet add package peremunoz.WindowsServices- .NET 8.0 or higher (including .NET 9 and .NET 10)
- Windows operating system
- Administrator privileges for install/uninstall/control operations
| Platform | Supported Versions |
|---|---|
| .NET | 8.0, 9.0, 10.0+ |
| Operating System | Windows only |
using peremunoz.WindowsServices;
var manager = new WindowsServiceManager();
// Install or update a service
var spec = new ServiceSpec(
Name: "MyTestService",
ExePath: @"C:\Services\MyService.exe",
DisplayName: "My Test Service",
Description: "A test Windows service",
StartMode: ServiceStartMode.Automatic,
DelayedAutoStart: false
);
var result = await manager.InstallOrUpdateAsync(spec);
if (result.Success)
{
Console.WriteLine(result.Message);
}
// Start a service
result = await manager.StartAsync("MyTestService");
// Stop a service
result = await manager.StopAsync("MyTestService");
// Restart a service
result = await manager.RestartAsync("MyTestService");
// Check service status
var status = await manager.GetStatusAsync("MyTestService");
Console.WriteLine($"Service status: {status}");
// Get detailed service info
var info = await manager.TryGetAsync("MyTestService");
if (info != null)
{
Console.WriteLine($"Name: {info.Name}");
Console.WriteLine($"Display: {info.DisplayName}");
Console.WriteLine($"Status: {info.Status}");
}
// Uninstall a service
result = await manager.UninstallIfExistsAsync("MyTestService");using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2));
// Start with custom timeout
var result = await manager.StartAsync(
"MyTestService",
timeout: TimeSpan.FromSeconds(45),
ct: cts.Token
);
// Restart with longer timeout
result = await manager.RestartAsync(
"MyTestService",
timeout: TimeSpan.FromMinutes(2),
ct: cts.Token
);var result = await manager.StartAsync("MyService");
if (result.Success)
{
Console.WriteLine($"? {result.Message}");
}
else
{
Console.WriteLine($"? {result.Code}: {result.Message}");
if (result.Exception != null)
{
Console.WriteLine($" Exception: {result.Exception.Message}");
}
}OK- Operation succeededALREADY_RUNNING- Service was already running (Start operation)ALREADY_STOPPED- Service was already stopped (Stop operation)NOT_INSTALLED- Service does not existTIMEOUT- Operation exceeded the specified timeoutWIN32_ERROR- Windows API error occurredCANCELED- Operation was canceled via CancellationTokenERROR- General error occurred
Main interface for service management operations.
Task<ServiceInfo?> TryGetAsync(string name, CancellationToken ct = default)- Non-throwing service info queryTask<ServiceStatus> GetStatusAsync(string name, CancellationToken ct = default)- Get service statusTask<OpResult> InstallOrUpdateAsync(ServiceSpec spec, CancellationToken ct = default)- Install or update serviceTask<OpResult> UninstallIfExistsAsync(string name, CancellationToken ct = default)- Uninstall serviceTask<OpResult> StartAsync(string name, TimeSpan? timeout = null, CancellationToken ct = default)- Start serviceTask<OpResult> StopAsync(string name, TimeSpan? timeout = null, CancellationToken ct = default)- Stop serviceTask<OpResult> RestartAsync(string name, TimeSpan? timeout = null, CancellationToken ct = default)- Restart service
Configuration for service installation/update.
string Name- Service name (required)string ExePath- Path to executable (required)string? Arguments- Command-line arguments (optional)string? DisplayName- Display name (optional, defaults to Name)string? Description- Service description (optional)ServiceStartMode StartMode- Start mode (default: Automatic)bool DelayedAutoStart- Delayed auto-start flag (default: false)
Unknown- Status could not be determinedNotInstalled- Service doesn't existStopped- Service is stoppedStartPending- Service is startingStopPending- Service is stoppingRunning- Service is runningPausePending- Service is pausingPaused- Service is pausedContinuePending- Service is resuming
See LICENSE.txt for license information.
Contributions are welcome! Please feel free to submit issues or pull requests.