Table of Contents
- Introduction
- Getting Started
- Features
- Overview
- Demo Video
- Comparison with Alternatives
- Source Code
- Points of Interest
- Acknowledgments
- 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
Chocolatey
choco install -y servy
Scoop
scoop bucket add extras
scoop install servy
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+Cfor 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.
Recovery
Here you can set up recovery actions (restart, stop, or run a failure program) to automatically handle process crashes and failed health checks.
Advanced
The advanced tab provides additional configuration options such as environment variables and service dependencies.
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.
You can also run the service under:
NT AUTHORITY\NetworkServiceNT AUTHORITY\LocalService- Passwordless accounts
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.
Post-Launch
Configure an optional post-launch program that runs after the process starts successfully.
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).
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.
CLI / PowerShell
Servy also comes with a PowerShell module and CLI commands, enabling full automation and integration into CI/CD pipelines.
CLI
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
mainbranch - .NET Framework 4.8 version: located on the
net48branch
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 | 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. │
│ │
└───────────────────────────────────┘
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.
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.dbby 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
- Define SQL Queries – Queries are written explicitly in the repository classes.
-
Execute with Dapper –
IDbConnectionis used with Dapper's extension methods such asQuery<T>()andExecute(). -
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();
}
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:
- OnStart - Load configuration and start target process
- OnStop - Gracefully terminate target process
Servy.Restarter (Restart Manager)
Utility component for handling service restart.
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.














Top comments (0)