DEV Community

Cover image for Servy: Turn Any App into a Native Windows Service
aelassas
aelassas

Posted on

Servy: Turn Any App into a Native Windows Service

Table of Contents

  1. Introduction
  2. Getting Started
  3. Features
  4. Overview
    1. Desktop App
    2. Manager App
    3. CLI/PowerShell
  5. Demo Video
  6. Comparison with Alternatives
  7. Source Code
    1. Technology Stack
    2. Project Structure
    3. Architecture Layers
    4. Project Details
    5. Integration Flow
    6. Design Patterns
    7. Unit Tests
  8. Points of Interest
  9. Acknowledgments
  10. See Also

Introduction

Whenever I needed to run an app as a Windows service, I usually relied on tools like sc.exe, NSSM, or WinSW. They get the job done, but in real projects, their limitations quickly became frustrating.

sc.exe only works with applications that are specifically designed to run as Windows services. It also always defaults to C:\Windows\System32 as the working directory, which can break apps that rely on relative paths or local configuration files. NSSM is lightweight, but it doesn't offer monitoring, health checks, pre-launch and post-launch hooks, or a fully-featured user interface. WinSW is configurable, but it's XML-based, not very user-friendly for quick setups, and also lacks a proper UI.

After running into these issues too many times, I decided to build my own tool.

The goals

I wanted a solution that was easy to use, with a clean desktop app, but also scriptable through CLI and PowerShell for automation and CI/CD pipelines. It needed to be flexible enough to run any type of app—Node.js, Python, .NET, scripts, and more. It also had to be robust, with built-in logging, health checks, recovery options, pre-launch and post-launch hooks, CPU and RAM monitoring, and restart policies. Finally, it had to work across a wide range of Windows versions, from Windows 7 to Windows 11, including Server editions.

The result

The result is Servy, a tool that lets you run any app as a native Windows service with full control over the working directory, startup type, process priority, logging, health checks, environment variables, dependencies, hooks, and parameters. Servy is designed to be a full-featured alternative to NSSM, WinSW, and FireDaemon Pro.

Servy offers a desktop app, a CLI, and a PowerShell module that let you create, configure, and manage Windows services interactively or through scripts and CI/CD pipelines. It also includes a Manager app for easily monitoring and managing all installed services in real time.

If you've ever struggled with the limitations of the built-in sc tool or found NSSM lacking in features or UI, Servy might be exactly what you need. It solves a common limitation of Windows services by allowing you to set a custom working directory. The built-in sc tool only works with applications specifically designed to run as Windows services and always uses C:\Windows\System32 with no way to change it. This can break apps that depend on relative paths, configuration files, or local assets. Servy lets you run any app as a service and define the startup directory explicitly, ensuring it behaves exactly as if launched from a shortcut or command prompt.

Servy continuously monitors your app, restarting it automatically if it crashes, hangs, or stops. It is perfect for keeping non-service apps running in the background and ensuring they start automatically at system boot without having to rewrite them as services. Use it to run Node.js, Python, .NET, Java, Go, Rust, PHP, or Ruby applications; keep web servers, background workers, sync tools, or daemons alive after reboots; and automate task runners, schedulers, or scripts in production with built-in health checks, logging, and restart policies.

Getting Started

You have two options to install Servy. Download and install manually or use a package manager such as WinGet, Chocolatey, or Scoop.

Make sure you have WinGet, Chocolatey, or Scoop installed.

Run one of the following commands as administrator from Command Prompt or PowerShell:

WinGet

winget install servy
Enter fullscreen mode Exit fullscreen mode

Chocolatey

choco install -y servy
Enter fullscreen mode Exit fullscreen mode

Scoop

scoop bucket add extras
scoop install servy
Enter fullscreen mode Exit fullscreen mode

Features

When it comes to features, Servy brings together the best parts of tools like NSSM, WinSW, and FireDaemon Pro — all in one easy-to-use package. It combines the simplicity of open-source tools with the flexibility and power you'd expect from professional service managers. Below is a detailed list of all the features Servy supports.

  • Clean, simple UI
  • Monitor and manage all installed services with Servy Manager
  • Real-time CPU and RAM usage tracking for installed services
  • CLI and PowerShell module for full scripting and automated deployments
  • Run any executable as a Windows service
  • Set service name, description, startup type, priority, working directory, environment variables, dependencies, and parameters
  • Environment variable expansion supported in both environment variables and process parameters
  • Run services as Local System, Local Service, Network Service, local user, domain account, or gMSA
  • Redirect stdout/stderr to log files with automatic size-based rotation
  • Run pre-launch hook before starting the service, with retries, timeout, logging and failure handling
  • Run post-launch hook after the application starts successfully
  • Supports Ctrl+C for command-line apps, close-window for GUI apps, and force kill if unresponsive
  • Prevent orphaned/zombie processes with improved lifecycle management and ensuring resource cleanup
  • Health checks and automatic service recovery
  • Browse and search logs by level, date, and keyword for faster troubleshooting from Servy Manager
  • Export/Import service configurations
  • Service Event Notification alerts on service failures via Windows notifications and email
  • Compatible with Windows 7–11 x64 and Windows Server editions

Overview

Servy provides a modern and intuitive interface to run any app as a native windows service with powerful configuration and management options.

The following figures illustrate the key parts of the desktop app, Manager app, and CLI/PowerShell integration.

Service details

This tab lets you configure the main service properties such as name, description, executable path, startup directory, and startup type.

servy main

Recovery

Here you can set up recovery actions (restart, stop, or run a failure program) to automatically handle process crashes and failed health checks.

servy recovery

Advanced

The advanced tab provides additional configuration options such as environment variables and service dependencies.

servy advanced

Log On

This tab allows you to configure the service account, including support for local accounts, domain accounts, and gMSA accounts.

Servy securely encrypts stored passwords using AES. For more details, see the Security page.

servy logon 1

You can also run the service under: 

  • NT AUTHORITY\NetworkService
  • NT AUTHORITY\LocalService
  • Passwordless accounts

servy logon 2

Important: Make sure to grant full access on %ProgramData%\Servy to NT AUTHORITY\NetworkService, NT AUTHORITY\LocalService, or whichever account runs the service.

Pre-Launch

Configure an optional pre-launch program that runs before the main service process starts. This can be used to prepare the environment, set up dependencies, or run initialization scripts.

servy Pre-Launch

Post-Launch

Configure an optional post-launch program that runs after the process starts successfully.

Servy Post-Launch

Manager

Servy Manager is a utility for Servy that provides a centralized interface to manage all services installed or imported into Servy.

Services

The Manager provides a central place to view all installed services, their status, CPU & RAM usage in real time, and quick actions (start, stop, restart, install, uninstall, remove, edit, copy PID).

Servy manager Services

Logs

Servy writes logs to the Windows Event Log, and its built-in log viewer lets you inspect them in real time directly from the GUI.

servy logs

CLI / PowerShell

Servy also comes with a PowerShell module and CLI commands, enabling full automation and integration into CI/CD pipelines.

CLI

servy cli

PowerShell

servy PowerShell

Demo video

Comparison with Alternatives

The table below shows a comparison of Servy, NSSM and WinSW.

Feature Servy NSSM WinSW
GUI Management ✅ Real-time GUI for monitoring & configuration ⚪ Basic installer GUI only ❌ No GUI
CLI / Automation ✅ Full CLI support for scripting, PowerShell & CI/CD ✅ CLI ✅ CLI only
Run any executable as service
Environment variables & expansion ✅ Fully supported ⚪ Basic ⚪ Basic
Service accounts ✅ Local System, local user, domain, or gMSA ⚪ Limited ⚪ Limited
Pre-launch hooks, retries, timeouts ✅ Advanced lifecycle options ⚪ Basic
Post-launch hooks ✅ Advanced lifecycle options ⚪ Basic
Stdout/stderr logging with rotation ✅ Automatic, configurable ⚪ Basic ⚪ Basic
Health checks & automatic recovery ✅ Built-in monitoring & restart ⚪ Limited
CPU/RAM monitoring ✅ Real-time
Notifications & alerts ✅ Windows notifications + email
Export / Import service configs ✅ Supported
Supported OS Windows 7+, Server editions Windows 7+ Windows 7+
License / Cost ✅ Free & Open Source (MIT) ✅ Open Source ✅ Open Source
Actively Maintained ✅ Yes ❌ No (archived) ❌ No

Source Code

Servy is available in two versions, each maintained in a separate branch:

  • .NET 8.0+ version: located on the main branch
  • .NET Framework 4.8 version: located on the net48 branch

The Servy codebase has grown to around 22,000 lines of code, not including unit tests, build scripts, or automation workflows. It’s a fairly large project that covers everything from the core logic and service management engine to the desktop app, CLI, and background service. Even though it has many parts, the code is organized into clear, separate projects to keep things maintainable and easy to understand. This structure makes it easier to work on specific features or fix bugs without affecting other parts of the system.

Technology Stack

Core Technologies

  • .NET 8.0+ - Primary development framework
  • .NET Framework 4.8 - Development framework for compatibility with older Windows versions
  • WPF (Windows Presentation Foundation) - User interface
  • Windows API - Service management and system integration
  • Windows Services - Background process hosting

Development Tools

  • C# - Primary programming language
  • PowerShell - Automation and scripting
  • Visual Studio - IDE
  • Inno Setup - Installer creation
  • Mermaid - Architecture diagrams

System Requirements

  • Operating System: Windows 7 SP1 / 8 / 10 / 11 (x64) / Windows Server
  • Runtime: .NET 8.0+ / .NET Framework 4.8
  • Privileges: Administrator privileges (required for service installation)

Project Structure

The Servy solution consists of 8 main projects:

Project Structure

Project Type Description
Servy WPF Application Main user interface for service configuration and management
Servy.Manager WPF Application Main user interface for managing and monitoring installed services
Servy.UI WPF Class Library Shared components, services and WPF utilities
Servy.CLI Console Application Main CLI for service configuration and management
Servy.Core Class Library Shared functionality, utilities, and data models
Servy.Infrastructure Class Library Data access, persistence, and integration with external systems (e.g., SQLite database, configuration files)
Servy.Service Windows Service Windows Service executable that wraps target processes
Servy.Restarter Console Application Service restart utility

Architecture Layers

Servy follows Clean Architecture principles, separating responsibilities into distinct tiers for clarity, maintainability, and testability:

┌───────────────────────────────────┐
│                                   │
│        Presentation Layer         │
│                                   │
│    (Servy Apps - GUI & CLI)       │
│ Handles user interaction, input,  │
│ and output. Communicates with the │
│ business logic layer.             │
│                                   │
├───────────────────────────────────┤
│                                   │
│        Business Logic Layer       │
│                                   │
│            (Servy.Core)           │
│ Implements the core functionality,│
│ workflows, and service management │
│ rules, independent of UI.         │
│                                   │
├───────────────────────────────────┤
│                                   │
│      Infrastructure Layer         │
│                                   │
│     (Servy.Infrastructure)        │
│ Provides data persistence, access │
│ to the SQLite database, config    │
│ management, and external system   │
│ integration.                      │
│                                   │
├───────────────────────────────────┤
│                                   │
│          Service Layer            │
│                                   │
│          (Servy.Service)          │
│ A Windows Service host that runs  │
│ configured apps in the background,│
│ monitors them, and applies health │
│ checks and restart policies.      │
│                                   │
└───────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

The diagram above represents Servy's layered architecture following Clean Architecture principles. At the center is the Core layer (Servy.Core), which contains the domain entities (Service), abstractions/interfaces (IServiceRepository, IServiceManager), XML/JSON serialization, and password encryption. External services and APIs arereferenced here, following the dependency inversion principle. This layer is independent of external dependencies, ensuring business logic remains decoupled and testable.

Servy Diagram

The Infrastructure layer (Servy.Infrastructure) implements the Core interfaces, providing concrete functionality like database persistence (ServiceRepository).

The Application or Orchestrator layer coordinates domain operations, calling repositories and services, without containing business rules itself. In Clean Architecture terms, dependencies point inwards toward the Core, ensuring the inner domain remains stable even as infrastructure changes.

This separation allows for flexible testing, easier maintenance, and adaptability, as the domain logic does not rely on concrete implementations or frameworks.

Project Details

Servy (Main Application)

The main WPF application provides the user interface for creating and managing Windows services. The application is built using the MVVM (Model-View-ViewModel) design pattern to ensure clean separation of concerns and maintainable code architecture.

Key Responsibilities:

  • Provide user-friendly WPF interface for service configuration
  • Handle user input validation
  • Communicate with Windows Service Control Manager
  • Manage service installation, uninstallation, and configuration
  • Handle UAC elevation requests

Key Features:

  • Service name & description configuration
  • Startup type selection (Automatic, Manual, Disabled)
  • Process priority settings (Idle to Real Time)
  • Custom working directory and parameters
  • Output redirection with log rotation
  • Health checks and automatic service recovery
  • Environment variables
  • Service dependencies
  • Admin privilege management

Servy Manager

Servy Manager is the graphical interface for managing Windows services created with Servy. It provides an intuitive and centralized way to install, configure, and control services while persisting all configurations in a local database. Unlike directly working with the Windows Service Control Manager (SCM), Servy Manager adds a layer of convenience, advanced features, and structured service management.

Key Responsibilities:

  • Persist service information in a local database to maintain a consistent view of installed and imported services
  • Provide a user-friendly interface for managing the lifecycle of services (install, edit, start, stop, restart, copy PID, uninstall, remove)
  • Allow service configurations to be imported into the database without requiring immediate installation
  • Offer tools for viewing and editing service configurations directly within the application
  • Integrate with logging to make monitoring and troubleshooting services faster and more efficient

Key Features:

  • Service listing: View all services installed or imported in Servy
  • Service control: Start, stop, and restart services from the UI
  • Service installation: Install services from configuration files, uninstall or remove them when no longer needed
  • Export: Save service configurations in XML or JSON format
  • Import: Add service configurations to the database without installing them immediately
  • Configuration editor: Open and edit service configurations directly from the interface
  • Search: Quickly locate services by name or properties
  • Logs: Browse service logs with advanced filtering by log level, date, and keyword

Servy CLI (CLI)

The Servy CLI provides a text-based interface for advanced users and automation scenarios to create, configure, and manage Windows services. It complements the main WPF application by enabling scripting, CI/CD integration, and headless usage.

Key Responsibilities:

  • Configure Windows services via command line parameters and scripts
  • Install, uninstall, start, stop, and query services without UI
  • Support all service settings (name, description, startup type, priority, working directory, parameters)
  • Manage output redirection and log rotation programmatically
  • Request UAC elevation when required
  • Return meaningful exit codes for scripting automation and error handling

Key Features:

  • Full service lifecycle management (install, uninstall, start, stop)
  • Service configuration (name, description, startup type: automatic/manual/disabled)
  • Process priority adjustment (Idle to Real Time)
  • Custom working directory and command-line parameters
  • Stdout/stderr redirection with log rotation options
  • Health monitoring and automatic service recovery triggers
  • Environment variables
  • Service dependencies
  • Designed for scripting, CI/CD pipelines, and remote management
  • Admin privilege detection and elevation support

Note:

The CLI is designed as a lightweight, script-friendly alternative to the WPF interface, focusing on automation and headless scenarios while sharing core service management logic with the GUI application.

Servy.Core (Core Library)

Shared library containing common functionality used across all projects.

Key Responsibilities:

  • Implement common utilities and helper classes
  • Define interfaces and contracts

Core Components:

  • ServiceManager - Provides methods to install, uninstall, start, stop, restart, and update Windows services.
  • ServiceControllerWrapper - Defines an abstraction for controlling and monitoring the status of a Windows service.
  • WindowsServiceApi - Provides an abstraction for invoking native Windows Service API functions.
  • Win32ErrorProvider - Provides access to the last Win32 error code.
  • RotatingStreamWriter - Writes text to a file with automatic log rotation based on file size.

Servy.Infrastructure (Infrastructure layer)

The Infrastructure Layer is implemented in the Servy.Infrastructure project.

It is responsible for all data persistence and retrieval operations.

Responsibilities
  • Database Access – Interacts with Servy's SQLite database (Servy.db by default in %ProgramData%\Servy\db\).
  • Data Persistence – Reads and writes service configurations, logs, and related metadata.
Dapper ORM

Servy.Infrastructure uses Dapper, a lightweight Object–Relational Mapper (ORM) for .NET, to map database rows to strongly-typed C# objects.

Key benefits of using Dapper in Servy:

  • Performance – Minimal overhead compared to raw ADO.NET, making it suitable for high-frequency queries.
  • Simplicity – Allows writing SQL directly for clarity and control.
  • Type Safety – Automatically maps query results to Servy's DTOs and entity classes.
Usage Pattern
  1. Define SQL Queries – Queries are written explicitly in the repository classes.
  2. Execute with DapperIDbConnection is used with Dapper's extension methods such as Query<T>() and Execute().
  3. Return Mapped Objects – Results are returned as DTOs to the Business Logic Layer (Servy.Core).
using (var connection = new SQLiteConnection(connectionString))
{
    return connection.Query<ServiceDto>(
        "SELECT * FROM Services WHERE Name = @Name",
        new { Name = serviceName }
    ).FirstOrDefault();
}
Enter fullscreen mode Exit fullscreen mode

By keeping all persistence logic in Servy.Infrastructure, Servy maintains separation of concerns, ensuring that higher layers (Core, CLI, GUI) remain independent of the underlying storage mechanism.

Servy.Service (Windows Service)

Windows Service executable that wraps and manages target processes.

Key Responsibilities:

  • Act as Windows Service host
  • Launch and manage target executables
  • Handle process monitoring and restart logic
  • Redirect stdout/stderr with rotation
  • Apply process priority and working directory settings
  • Health checks and automatic service recovery
  • Run pre-launch and post-launch hooks
  • Handle service lifecycle operations
  • Prevent orphaned/zombie processes and ensuring resource cleanup

Service Lifecycle:

  1. OnStart - Load configuration and start target process
  2. OnStop - Gracefully terminate target process

Servy.Restarter (Restart Manager)

Utility component for handling service restart.

Integration Flow

Integration Flow

Design Patterns

Servy's architecture makes use of several well-known design patterns to keep the code organized, flexible, and easy to maintain.

The MVVM (Model–View–ViewModel) pattern is used throughout the Servy UI and Servy Manager projects. It cleanly separates the user interface from the business logic, which makes it easier to manage data bindings, handle user commands, and update the interface without mixing it with the logic. You can find these parts in the ViewModels, Models, and main XAML files.

The Factory Method pattern is used to create instances of different components, such as service controllers, process wrappers, stream writers, timers, and repositories. This helps Servy stay flexible by decoupling the code that uses these objects from the code that creates them. In other words, the app can easily switch to a new implementation without changing how it's used.

The Adapter pattern is used to make existing classes fit a specific interface expected by Servy. For example, ServiceControllerWrapper adapts the .NET ServiceController class, and RotatingStreamWriterAdapter and TimerAdapter do the same for stream writers and timers. Dapper-based repositories also use adapters to turn raw SQL results into strongly typed data objects.

The Singleton pattern appears in the StartOptionsParser, which acts as a single, global helper for parsing command-line options. This ensures there's just one consistent place to handle startup arguments.

The Strategy pattern helps Servy stay modular and configurable. The Service class depends on several interfaces—such as ILogger, IProcessFactory, IStreamWriterFactory, and ITimerFactory—that define interchangeable strategies for logging, process handling, timing, and more. Different implementations can be swapped in or out at runtime or for testing. The repositories in the data layer also follow this idea by using different query strategies depending on the operation.

The Observer pattern is used to monitor process activity. The IProcessWrapper interface defines events like OutputDataReceived, ErrorDataReceived, and Exited, which let other components react to what's happening inside a running process in real time.

The Dependency Injection pattern is used across Servy to keep classes loosely connected. Many classes, such as ServiceManager, ServiceCommands, and repository classes, receive their dependencies through their constructors. This makes the system easier to test and maintain since components don't create their own dependencies.

Finally, the Repository pattern is used to manage data access through SQLite. The repository classes encapsulate Dapper queries so that the rest of the system can work with strongly typed objects instead of SQL queries. This keeps database logic isolated and makes the code cleaner and easier to maintain.

Unit Tests

While developing Servy, I made sure to write unit tests for every project in the solution. These tests help keep the code stable, prevent regressions, and make it easier to add new features with confidence.

Project Description
Servy.UnitTests Tests for the main user interface used to configure and manage services.
Servy.Manager.UnitTests Tests for the interface that manages and monitors installed services.
Servy.UI.UnitTests Tests for shared UI components, helper services, and WPF utilities.
Servy.CLI.UnitTests Tests for the command-line interface that allows configuring and managing services through scripts or automation.
Servy.Core.UnitTests Tests for the shared logic, utilities, and data models used across the whole project.
Servy.Infrastructure.UnitTests Tests for data access, persistence, and integration with external systems like the SQLite database.
Servy.Service.UnitTests Tests for the Windows service executable that wraps and runs target applications.
Servy.Restarter.UnitTests Tests for the small utility responsible for restarting services when needed.

At the moment, code coverage is collected mainly for the Servy.Core and Servy.Infrastructure projects, since these contain the most critical business logic. The other projects focus more on UI or system-level behavior, which are harder to measure with automated coverage tools.

All tests are automatically run on every commit through the GitHub Actions workflow file test.yml. This workflow also sends coverage reports to Codecov and Coveralls, making it easy to track how much of the code is tested over time.

This setup helps catch issues early, ensures that every change is verified before being merged, and keeps Servy stable as it continues to grow.

Points of Interest

While building Servy, I spent quite a bit of time working directly with the Win32 API to handle various system-level operations such as managing processes, installing services, checking service states, and dealing with permissions. It was challenging at first, but it gave me a deeper understanding of how Windows manages background applications under the hood.

Publishing Servy on GitHub has been a huge help in improving the tool. It allowed me to find and fix bugs more quickly and also add new features that users requested, like the ability to expand environment variables. Most of the bugs were straightforward to reproduce and fix, but one issue took much longer to solve. When stopping a service, sending a Ctrl+C signal to the child process caused the stdout and stderr pipes to be lost. This meant the service could no longer receive any messages from the running application. It took some time and careful debugging to understand what was going on and find the right solution, but in the end, the bug was fixed and everything worked as expected. The process also gave me a better understanding of how Windows handles process communication. After a lot of effort, I was able to fix all the reported bugs and implement all the requested features, making Servy more stable, reliable, and user-friendly. Sharing the project on GitHub also made it easier to get feedback and suggestions, which helped guide development and prioritize improvements.

Posting Servy on Reddit also helped a lot in improving the project. Sharing it with the community meant that people could test it, give feedback, and suggest new features. Many of the ideas that made it into Servy came directly from users who tried it and pointed out what could be better. This kind of real-world input was really valuable because it showed me how people were actually using the tool, not just how I imagined it. It also helped me find small bugs or usability issues that I hadn't noticed before. Overall, putting Servy out there made it stronger, more polished, and more useful for everyone.

I also used PowerShell extensively to automate repetitive tasks like building, testing, CI/CD pipelines, and publishing new versions.

Most of Servy's automation is powered by GitHub Actions, which runs automatically whenever I create a new release. With the GitHub Actions workflows I've set up, every time I publish a new release, the build is automatically pushed to WinGet, Chocolatey, and Scoop, and the version number is bumped for the next cycle. Setting this up took a fair amount of trial and error, but once everything started working, it completely changed the release process. Now maintaining and releasing Servy is almost effortless. Everything happens automatically, which saves a lot of time and makes it easier to focus on improving the tool instead of worrying about builds or deployments. Now the whole process of maintaining and releasing Servy is almost completely automatic. New versions are built, tested, and published with very little manual work, which saves a lot of time and makes updates much easier to manage.

That's it! I hope you find Servy useful and consider using it in your own projects. Feedback and contributions are welcome.

Acknowledgments

A huge thanks to JetBrains for providing an open-source license for their tools. Their software made it much easier to profile, debug, and optimize Servy, helping improve its performance and stability. Having access to these professional tools really made a difference during development and saved a lot of time.

I'd also like to thank everyone who tested Servy, reported issues, and suggested improvements on GitHub and Reddit. Your feedback and contributions helped shape the project and made it better with every release.

See Also

Top comments (0)