McpNetwork.WinNuxService 11.1.0

dotnet add package McpNetwork.WinNuxService --version 11.1.0
                    
NuGet\Install-Package McpNetwork.WinNuxService -Version 11.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="McpNetwork.WinNuxService" Version="11.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="McpNetwork.WinNuxService" Version="11.1.0" />
                    
Directory.Packages.props
<PackageReference Include="McpNetwork.WinNuxService" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add McpNetwork.WinNuxService --version 11.1.0
                    
#r "nuget: McpNetwork.WinNuxService, 11.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package McpNetwork.WinNuxService@11.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=McpNetwork.WinNuxService&version=11.1.0
                    
Install as a Cake Addin
#tool nuget:?package=McpNetwork.WinNuxService&version=11.1.0
                    
Install as a Cake Tool

McpNetwork.WinNuxService

McpNetwork.WinNuxService is a lightweight .NET library that simplifies building cross-platform services that run as:

  • Windows Services
  • Linux systemd services
  • Console applications (for debugging)
  • macOS background processes (via launchd)

Built on top of the .NET Generic Host, it provides a clean abstraction to build modular services and plugin-based architectures.

Compatible with .NET 10+.


Features

  • Run the same application as Windows Service, Linux systemd service, or console app
  • Built on Microsoft.Extensions.Hosting
  • Full Dependency Injection
  • Built-in Logging integration
  • Multiple services in one host
  • Plugin architecture
  • Dynamic plugin loading
  • Optional plugin hot-reload
  • Define and access service metadata at startup (ServiceName, Environment, Version, custom properties)

Installation

dotnet add package McpNetwork.WinNuxService

Quick Start

using McpNetwork.WinNuxService;

await WinNuxService
    .Create()
    .WithName("MyService")
    .WithEnvironment("Staging")
    .WithVersion("1.2.3")
    .AddProperty("GitCommit", "abc123def")
    .AddService<TestService>()
    .RunAsync();

Your application automatically runs correctly as:

  • Windows Service
  • Linux systemd service
  • Console application

Service Metadata and Build-Time Info

WinNuxService allows you to define service metadata at startup. This information is stored in a WinNuxServiceInfo object, which is available via Dependency Injection in all your services.

Configuring Metadata

var host = WinNuxService
    .Create()
    .WithName("MyService")                    // Sets the service name
    .WithEnvironment("Staging")               // Sets the environment
    .WithVersion("1.2.3")                     // Sets the version
    .AddProperty("GitCommit", "abc123def")  // Add custom key/value
    .AddService<TestService>()
    .Build();
  • WithName(string) – sets the service name
  • WithEnvironment(string) – sets the environment (Development, Staging, Production)
  • WithVersion(string) – sets the service version
  • AddProperty(string key, string value) – adds any custom property

Accessing Metadata in Services

public class TestService : IWinNuxService
{
    private readonly WinNuxServiceInfo _info;

    public TestService(WinNuxServiceInfo info)
    {
        _info = info;
    }

    public Task OnStartAsync(CancellationToken token)
    {
        Console.WriteLine($"Starting {_info.ServiceName} ({_info.Environment}) version {_info.Version}");
        foreach (var prop in _info.Properties)
        {
            Console.WriteLine($"Property: {prop.Key} = {prop.Value}");
        }

        return Task.CompletedTask;
    }

    public Task OnStopAsync(CancellationToken token)
    {
        Console.WriteLine($"Stopping {_info.ServiceName}");
        return Task.CompletedTask;
    }
}

Running the Host

await host.RunAsync();  // blocking run

// or start/stop programmatically
await host.StartAsync();
await host.StopAsync();
  • RunAsync() – runs the service host (blocking)
  • StartAsync() / StopAsync() – for finer control

Creating a Service Module

Service modules implement IWinNuxService.

public class TestService : IWinNuxService
{
    public Task OnStartAsync(CancellationToken token)
    {
        _ = RunLoop(token);
        return Task.CompletedTask;
    }

    public Task OnStopAsync(CancellationToken token)
    {
        Console.WriteLine("Service stopping");
        return Task.CompletedTask;
    }

    private async Task RunLoop(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine("Service running");
            await Task.Delay(5000, token);
        }
    }
}

Running Multiple Services

await WinNuxService
    .Create()
    .AddService<ServiceA>()
    .AddService<ServiceB>()
    .AddService<ServiceC>()
    .RunAsync();

All services run inside the same host process.


Dependency Injection

Standard .NET DI works out of the box.

.ConfigureServices((ctx, services) =>
{
    services.AddSingleton<IDatabase, Database>();
})

Services receive dependencies through constructor injection.


Logging

.ConfigureLogging(logging =>
{
    logging.AddConsole();
})

Compatible with:

  • Serilog
  • NLog
  • Application Insights
  • any Microsoft.Extensions.Logging provider

Minimal Example (~60 lines)

Program.cs

using McpNetwork.WinNuxService;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

await WinNuxService
    .Create()
    .WithName("HeartbeatHost")
    .WithVersion("1.0.0")
    .AddService<HeartbeatService>()
    .AddService<TimeService>()
    .ConfigureServices((ctx, services) =>
    {
        services.AddSingleton<IMessenger, ConsoleMessenger>();
    })
    .ConfigureLogging(logging => logging.AddConsole())
    .RunAsync();

public interface IMessenger { void Send(string message); }

public class ConsoleMessenger : IMessenger
{
    public void Send(string message) => Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {message}");
}

HeartbeatService.cs

public class HeartbeatService : IWinNuxService
{
    private readonly IMessenger _messenger;

    public HeartbeatService(IMessenger messenger) { _messenger = messenger; }

    public Task OnStartAsync(CancellationToken token)
    {
        _ = RunLoop(token);
        return Task.CompletedTask;
    }

    public Task OnStopAsync(CancellationToken token)
    {
        _messenger.Send("HeartbeatService stopping");
        return Task.CompletedTask;
    }

    private async Task RunLoop(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            _messenger.Send("HeartbeatService alive");
            await Task.Delay(3000, token);
        }
    }
}

TimeService.cs

public class TimeService : IWinNuxService
{
    private readonly IMessenger _messenger;

    public TimeService(IMessenger messenger) { _messenger = messenger; }

    public Task OnStartAsync(CancellationToken token)
    {
        _ = RunLoop(token);
        return Task.CompletedTask;
    }

    public Task OnStopAsync(CancellationToken token)
    {
        _messenger.Send("TimeService stopping");
        return Task.CompletedTask;
    }

    private async Task RunLoop(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            _messenger.Send($"Current time: {DateTime.Now}");
            await Task.Delay(5000, token);
        }
    }
}

Plugin Architecture

Plugins can be loaded dynamically from external assemblies.

Example directory structure:

MyService/
│
├── MyService.exe
│
└── plugins/
    ├── PluginA/
    │   ├── PluginA.dll
    │   └── dependencies
    │
    └── PluginB/
        ├── PluginB.dll
        └── dependencies

Each plugin is loaded using its own AssemblyLoadContext, allowing:

  • dependency isolation
  • different dependency versions
  • safe unloading
  • runtime reloading

Plugin Reloading

Plugins can be reloaded without restarting the main host.

Reload sequence:

  1. Stop plugin
  2. Cancel running tasks
  3. Unload AssemblyLoadContext
  4. Load new assembly
  5. Restart plugin

This enables live updates in production environments.


Platform Support

Platform Support
Windows Windows Service
Linux systemd
macOS Console / launchd

When Should You Use WinNuxService?

Background Processing Server

Examples:

  • queue consumers
  • batch processing
  • scheduled jobs

IoT Gateway

Examples:

  • device communication
  • telemetry processing
  • protocol plugins

Plugin-Based Enterprise Services

Examples:

  • dynamically extend server capabilities
  • load new modules without redeploying
  • isolate external dependencies

Requirements

  • .NET 10 or later
  • Windows / Linux / macOS

License

McpNetwork.WinNuxService is licensed under the MIT License. See LICENSE for more information.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
11.1.0 39 3/13/2026
11.0.0 75 3/11/2026
10.0.0 108 1/16/2026
8.1.0 398 12/8/2023
7.1.0 220 12/8/2023
7.0.0 522 11/13/2022
6.1.0 242 12/8/2023
6.0.0 1,331 11/19/2021
1.1.1 509 5/24/2021
1.0.3 787 5/16/2021 1.0.3 is deprecated because it is no longer maintained.