Open-source project
winsw/winsw avatar
winsw/winsw

WinSW locates its configuration by filename adjacency, and nearly every command needs Administrator

A wrapper executable that can run any executable as a Windows service, in a permissive license.

14,430 stars1,712 forksC#MIT

At a glance

What is it?
WinSW is an MIT licensed wrapper that turns any executable into a Windows service, with configuration in an XML file and two ways to invoke it, as a global tool or as a renamed bundled binary. The design is small enough to read in one sitting, and the sharp edges are all in the packaging: the XML must sit beside the executable, most commands trigger a UAC prompt, and the package managers still serve the 2.x line while 3.x sits on its own branch.
Who is it for?
Use WinSW when you already know the shape of your XML and want a service wrapper with no run-time framework to install on hosts that have .NET Framework 4.6.1. Pick the .NET 7 native build only when the host is on Windows 10 version 1607 or later, and plan for an interactive operator, because install, start and stop all prompt for UAC.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 108 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • winsw/winsw14,430 ★ · +110
Star history
Repository2026-09-222026-11-14
winsw/winsw14.3k14.4k

110 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Bundled mode works because the XML sits next to the renamed executable

The bundled route is four steps, and the third one carries the whole design:

1. Take *WinSW.exe* or *WinSW.zip* from the distribution, and rename the *.exe* to your taste (such as *myapp.exe*). 1. Write *myapp.xml*. 1. Place those two files side by side, because that's how WinSW discovers its co-related configuration. 1. Run `myapp.exe install [options]`, then `myapp.exe start`.

Discovery is filename adjacency, so the rename is not cosmetic, it is the handle the service will use. The failure this creates is quiet: move the executable without the XML, or copy the XML to another directory for editing, and the installed service now points at a directory with no configuration in it. The same reasoning explains why the service identity lives in the XML. In the Jenkins sample that identity is `<id>jenkins</id>` with `<name>Jenkins</name>` and a description, so renaming myapp.exe does not rename the service in the services list, the id element does.

Global mode makes you name the XML on every command

The alternative is to keep the binary named WinSW.exe and pass the configuration file on each call:

code
winsw install myapp.xml [options]
winsw start myapp.xml
winsw status myapp.xml

The tradeoff against bundled mode is direct. In bundled mode the filename is implicit and the command is short; in global mode nothing is implicit, so any script, scheduled task or deployment pipeline that touches the service has to carry myapp.xml with it, and a typo surfaces as a missing file rather than as a stopped service. The command set is the same in both modes: install, uninstall, start, stop, restart, status, refresh, customize, plus a dev prefix for experimental commands. Two of those deserve attention before you rely on them. refresh updates service properties without a reinstall, and customize rebuilds the wrapper executable itself. Both change state that you would otherwise have to recreate by uninstalling, which means a deployed service can drift from the file you think defines it.

NuGet and Maven still serve 2.x while the default branch is 3.x

The distribution story has three layers and they do not agree on a version. GitHub Releases holds stable 2.x releases alongside 3.x pre-releases. NuGet and Maven packages currently correspond to 2.x, and the Maven packaging is hosted by the Jenkins project with binaries served from repo.jenkins-ci.org. Meanwhile development of 3.x happens on the default branch v3, and 2.x documentation lives on the v2 branch. The releases listed for the repository are v3.0.0-alpha.11 from 2023-01-29, v2.12.0 from 2023-01-28 and v3.0.0-alpha.10 from 2021-08-09, while the last push to the default branch is 2026-07-30. The consequence is concrete. A package manager install gives you the older design, not the newer one, and a build from the v3 branch is newer than anything in that release list. If your decision depends on 3.x behaviour, take the binary from GitHub Releases and confirm which line you are on, because the channel you install from silently decides it for you.

Two build flavors with different Windows floors, chosen when you download

WinSW 3 runs on Windows platforms that have .NET Framework 4.6.1 or later installed. For systems without .NET Framework, the project provides native 64-bit and 32-bit executables based on .NET 7, and more executables can be added upon request. The two flavors do not reach back the same distance in time. .NET Framework 4.6.1 has been preinstalled since Windows 10 version 1511 and Windows Server 2016, and has been installable since Windows 7 SP1 and Windows Server 2008 R2 SP1. The .NET 7 builds require Windows 10 version 1607, Windows Server Core 2012 R2 or Nano Server version 1809. So on a Server 2012 R2 host without the framework you take the .NET 7 build, and on a Windows 7 SP1 host you cannot, because that host predates the .NET 7 floor. The choice is made at download time and it is not something the wrapper can renegotiate at runtime, which is why picking the wrong executable turns into a service that will not start.

Administrator rights for install, start and stop means a UAC prompt in automation

The privilege requirement is stated once and applies broadly: most commands require Administrator privileges to execute, and WinSW will prompt for UAC in non-elevated sessions. That is the normal cost of registering a Windows service, but it has an operational shape worth planning for. An operator running install from an ordinary shell gets an elevation prompt, so the first install is an interactive step. Anything that later manages the service through a scheduler or a deployment agent inherits the same requirement. The experimental commands sit in the same category. `dev ps` draws the process tree associated with the service, `dev kill` terminates the service if it has stopped responding, and `dev list` lists services managed by the current executable. `dev kill` in particular is a blunt instrument, so it belongs in a documented runbook rather than in an automated health loop.

Four samples ship in the repo, and four alternatives are named without a comparison

The samples directory holds four configurations: minimal.xml, jenkins.xml, complete.xml and shared-directory-mapper.xml. That set is a reasonable reading order, because minimal.xml is the smallest thing that runs, jenkins.xml is the one printed on the front page, and complete.xml is where the optional elements live. Since the configuration file is the entire interface, those four files are the real documentation, alongside docs/xml-config-file.md for the specification, docs/logging-and-error-reporting.md, docs/extensions/extensions.md, and use case notes on self-restarting services and deferred file operations. The alternatives section is thinner. Four projects are named, srvany.exe, nssm, srvany-ng and shawl, each with a link, and no comparison is offered. So if you are choosing a wrapper, the repository tells you that alternatives exist and then leaves the decision to you, which means the migration guide docs/migrate-to-3-x.md and the troubleshooting notes are the documents worth reading first.

%BASE% ties paths to the install directory, which makes relocation a reinstall

The sample configuration the project shows is the one used by the Jenkins project:

xml
<service>
  <id>jenkins</id>
  <name>Jenkins</name>
  <description>This service runs Jenkins continuous integration system.</description>
  <env name="JENKINS_HOME" value="%BASE%"/>
  <executable>java</executable>
  <arguments>-Xrs -Xmx256m -jar "%BASE%\jenkins.war" --httpPort=8080</arguments>
  <log mode="roll"></log>
</service>

Two mechanisms carry the portability here. The executable is the bare word `java`, so the wrapper resolves it through PATH rather than hardcoding an install location, and `%BASE%` is what anchors the rest to wherever the wrapper was installed, which is why the war path works without an absolute path. The logging line is equally terse: `log mode="roll"` selects rolling files and nothing in the sample says how large a file may grow or how many are kept, so disk behaviour is a decision you have to make in the logging documentation rather than something the primitive example sets for you.

Editorial conclusion

Use WinSW when you already know the shape of your XML and want a service wrapper with no run-time framework to install on hosts that have .NET Framework 4.6.1. Pick the .NET 7 native build only when the host is on Windows 10 version 1607 or later, and plan for an interactive operator, because install, start and stop all prompt for UAC. Do not pull WinSW from NuGet or Maven expecting the 3.x design; those packages still correspond to 2.x. Before you ship a service, install it from the directory it will live in, decide what your log mode does to disk, and check the refresh and customize commands, which can change a service without reinstalling it.

Frequently asked questions

What is WinSW?

WinSW is a wrapper executable that runs any executable as a Windows service, licensed under MIT. WinSW 3 runs on Windows with .NET Framework 4.6.1 or later, and native 64-bit and 32-bit builds based on .NET 7 exist for systems without it.

how to install winsw

Take WinSW.exe or WinSW.zip from the distribution, write myapp.xml, and place the two files side by side. Then run `myapp.exe install [options]` and `myapp.exe start`. Most commands require Administrator privileges, and WinSW prompts for UAC in a non-elevated session.

What is a Windows service wrapper?

A wrapper that runs another executable as a Windows service. WinSW does this with an XML configuration file, and it names srvany.exe, nssm, srvany-ng and shawl as similar projects.

What are the key differences between WinSW and NSSM?

The repository lists nssm among similar projects but publishes no comparison. What it states about WinSW is that it wraps and manages any application as a Windows service under a permissive MIT license, configured through an XML file.

is winsw safe

The project makes no security claim beyond its MIT license. Its documented download sources are GitHub Releases, Azure Pipelines CI builds, NuGet, and Maven packaging hosted by the Jenkins project.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. winsw/winsw on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/winsw-winsw.svg)](https://hysenlabs.com/projects/winsw-winsw)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/winsw-winsw.svg)](https://hysenlabs.com/projects/winsw-winsw)

Was this useful?