A safer way to deploy Windows Services
WinService.Deploy is a project-agnostic .NET 8 console tool that automates the full deployment lifecycle for Windows Services — stop, backup, copy, verify, restart — with automatic rollback if any step fails. Built after one too many manual deployments left a service in a broken, undocumented state.
The problem
Manual Windows Service deployments are error-prone: a failed copy or a service that won't restart can leave production in a broken, undocumented state with no clean way back. Generic deployment tools either assume a Linux/container target or are too heavyweight to justify for a single Windows Service on a single box.
What I built
A project-agnostic .NET 8 console tool that automates the full deployment lifecycle — stop, backup, copy, verify, restart — with automatic rollback if any step fails. It ships as a self-contained executable with an interactive Spectre.Console UI, a WhatIf dry-run mode, and full deployment logging for audit and troubleshooting.
Engineering decisions
Why BLAKE3 for file verification instead of a simpler checksum?
Deployments can involve hundreds of files, and hashing needs to be fast enough that verification doesn't meaningfully extend deployment time. BLAKE3 is significantly faster than SHA-256 at the file sizes involved here while still being cryptographically sound for detecting corruption, which is the actual threat model — not adversarial tampering.
Why automatic rollback instead of just alerting on failure?
The entire motivation for the tool was deployments that fail midway and leave a service in a broken state with no fast way back. Alerting alone doesn't solve that — the person on call still has to manually reconstruct the previous state under pressure. Automatic rollback to the last versioned backup removes that step entirely.
Why a WhatIf dry-run mode?
A deployment tool that touches production services needs a way to validate configuration — paths, service name, permissions — without risk. WhatIf simulates the entire deployment, including what a rollback would do, with zero filesystem or service changes, so a new deployment target can be tested safely before the first real run.
Why ship as a self-contained executable rather than requiring a .NET install on the target?
Production Windows servers don't always have the matching .NET runtime installed, and requiring it adds a dependency the tool shouldn't need. A self-contained publish bundles the runtime with the executable, so it runs on a clean target server with no prerequisites beyond Windows itself.
Operational details
Deployment logging
Every step writes a timestamped entry to a deployment log, giving a full audit trail for troubleshooting after the fact.
Retention-based cleanup
Old backups are automatically pruned based on a configurable retention period, keeping disk usage on the deploy target bounded.
Remote deployment
Supports deploying to a remote server over a UNC network share, not just localhost, for centrally-managed infrastructure.
Configurable per project
Settings live in appsettings.json, so the same tool covers multiple services with separate configurations rather than being hardcoded to one.