WinSW 使用与 XML 配置完全指南
基于 winsw/winsw 官方仓库(v3 分支文档)整理
整理日期:2026-06-10
一、WinSW 是什么?
WinSW(Windows Service Wrapper) 是一个采用宽松 MIT 许可证的开源工具,它可以把任意可执行程序包装并管理为 Windows 服务。
简单来说:很多程序(如 Java 程序、Node.js 应用、Python 脚本、各类控制台程序)本身并不支持作为 Windows 服务运行,而 WinSW 充当一个"包装器",让这些程序能够:
- 开机自动启动,无需用户登录
- 在后台静默运行
- 崩溃后自动重启
- 由 Windows 服务管理器(services.msc)统一管理
- 自动捕获并记录程序的标准输出 / 标准错误日志
典型应用场景
| 场景 | 说明 |
|---|---|
| 部署 Java 应用 | 如 Jenkins、Spring Boot 应用(Jenkins 官方就在使用 WinSW) |
| 部署 Node.js / Python 服务 | 让脚本类程序以服务方式常驻后台 |
| 部署中间件 | 如 frp、nginx、各类代理或网关工具 |
| 自更新服务 | 配合 <download> 元素实现服务启动前自动拉取最新文件 |
项目状态与支持平台
- 当前开发分支为 v3(默认分支),GitHub Releases 上提供稳定的 2.x 版本和 3.x 预发布版本;NuGet 和 Maven 包目前对应 2.x。
- WinSW 3 运行要求:安装了 .NET Framework 4.6.1 及以上版本的 Windows(Windows 10 1511 / Windows Server 2016 起系统已预装);对于没有 .NET Framework 的系统,项目提供基于 .NET 7 的原生 64 位和 32 位独立可执行文件。
- 同类项目对比:srvany.exe、NSSM、srvany-ng、shawl。WinSW 的优势在于许可证宽松(MIT)、配置灵活(XML)、功能丰富(日志滚动、失败自动重启、文件下载等)。
二、快速上手
WinSW 有两种使用方式:
方式一:作为全局工具(Global Tool)
- 从 GitHub Releases 下载
WinSW.exe - 编写配置文件
myapp.xml - 安装服务:
winsw install myapp.xml [options] - 启动服务:
winsw start myapp.xml - 查看状态:
winsw status myapp.xml
方式二:作为捆绑工具(Bundled Tool,推荐用于分发)
- 下载
WinSW.exe并重命名为你的服务名,如myapp.exe - 编写同名配置文件
myapp.xml - 将两个文件放在同一目录下(WinSW 通过同名规则自动发现配置文件)
- 安装服务:
myapp.exe install [options] - 启动服务:
myapp.exe start
⚠️ 大多数命令需要管理员权限。在非提权会话中,WinSW 会自动弹出 UAC 提示。
最简示例(Jenkins 官方配置)
<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>
三、CLI 命令大全
| 命令 | 说明 |
|---|---|
install |
安装服务 |
uninstall |
卸载服务 |
start |
启动服务 |
stop |
停止服务 |
restart |
重启服务(先停后启) |
status |
查看服务状态 |
refresh |
不重装服务的情况下刷新服务属性 |
customize |
定制包装器可执行文件 |
dev ps |
(实验性)绘制服务关联的进程树 |
dev kill |
(实验性)强制终止无响应的服务 |
dev list |
(实验性)列出当前可执行文件管理的所有服务 |
命令详细用法
所有接受 <path-to-config> 参数的命令,如果不指定配置文件路径,WinSW 会在可执行文件所在目录中查找与可执行文件同名的 .xml 文件。
install — 安装服务
winsw install [<path-to-config>] [--no-elevate] [--user|--username <username>] [--pass|--password <password>]
| 选项 | 说明 |
|---|---|
--no-elevate |
不自动触发 UAC 提权提示 |
--user / --username <username> |
指定服务账户的用户名 |
--pass / --password <password> |
指定服务账户的密码 |
uninstall — 卸载服务
winsw uninstall [<path-to-config>] [--no-elevate]
start — 启动服务
winsw start [<path-to-config>] [--no-elevate]
stop — 停止服务
winsw stop [<path-to-config>] [--no-elevate] [--no-wait]
| 选项 | 说明 |
|---|---|
--no-elevate |
不自动触发 UAC 提权提示 |
--no-wait |
不等待服务真正停止就返回 |
--force |
即使该服务已启动了依赖它的服务,也强制停止 |
restart — 重启服务
winsw restart [<path-to-config>] [--no-elevate]
| 选项 | 说明 |
|---|---|
--force |
即使存在已启动的依赖服务,也强制重启 |
status — 查看服务状态
winsw status [<path-to-config>]
refresh — 刷新服务属性
winsw refresh [<path-to-config>] [--no-elevate]
修改 XML 配置后,无需卸载重装即可让部分服务属性生效。
customize — 定制可执行文件
winsw customize -o|--output <output> --manufacturer <manufacturer>
| 选项 | 说明 |
|---|---|
-o / --output <output> |
必填,输出文件路径 |
--manufacturer <manufacturer> |
指定定制后可执行文件的厂商名称 |
dev 系列(实验性命令)
winsw dev ps [<path-to-config>] [-a|--all] # 绘制进程树;--all 显示所有服务
winsw dev kill [<path-to-config>] [--no-elevate] # 强杀无响应服务
winsw dev list # 列出本可执行文件管理的服务
四、XML 配置文件详解
4.1 基本规则
- 根元素必须是
<service>,所有配置项都是它的子元素。 - 环境变量展开:配置文件中可使用
%Name%形式引用环境变量,WinSW 会自动替换为实际值;引用未定义的变量则不做替换。 - 内置变量
%BASE%:WinSW 自动设置环境变量BASE,指向 WinSW 可执行文件(重命名后的)所在目录,常用于引用同目录下的其他文件。该变量同样会传递给子进程。 - 相对路径:基于工作目录(
<workingdirectory>)解析;默认工作目录为配置文件所在目录。
4.2 配置参数总览表
| 参数 | 必填 | 默认值 | 作用简述 |
|---|---|---|---|
<id> |
✅ | — | 服务的系统唯一标识 |
<executable> |
✅ | — | 要启动的可执行程序 |
<name> |
否 | — | 服务显示名称 |
<description> |
否 | — | 服务详细描述 |
<startmode> |
否 | Automatic |
启动模式:Automatic / Manual |
<delayedAutoStart> |
否 | false |
延迟自动启动 |
<depend> |
否 | — | 依赖的其他服务(可多个) |
<arguments> |
否 | — | 传给可执行程序的参数 |
<startarguments> |
否 | — | 启动参数(与 stoparguments 配套使用) |
<stopexecutable> |
否 | — | 停止服务时调用的程序 |
<stoparguments> |
否 | — | 停止程序的参数 |
<stoptimeout> |
否 | 15 sec |
优雅停止的等待超时 |
<prestart> 等 |
否 | — | 启动/停止前后的附加命令 |
<preshutdown> |
否 | — | 系统关机时给服务更多停止时间 |
<preshutdownTimeout> |
否 | 3 min |
关机前超时时间 |
<env> |
否 | — | 为子进程设置环境变量(可多个) |
<workingdirectory> |
否 | 配置文件目录 | 工作目录 |
<priority> |
否 | normal |
进程调度优先级 |
<hidewindow> |
否 | false |
隐藏控制台窗口 |
<interactive> |
否 | — | 允许服务与桌面交互 |
<beeponshutdown> |
否 | — | 服务关闭时发出蜂鸣(调试用) |
<log> / <logpath> |
否 | append 模式 | 日志捕获方式与目录 |
<onfailure> |
否 | — | 进程失败时的动作(可多个) |
<resetfailure> |
否 | 1 day |
失败计数重置时间 |
<download> |
否 | — | 启动前从 URL 下载文件(可多个) |
<serviceaccount> |
否 | LocalSystem | 服务运行账户 |
<securityDescriptor> |
否 | — | SDDL 格式安全描述符 |
<autoRefresh> |
否 | true |
自动刷新服务属性 |
<sharedDirectoryMapping> |
否 | — | 启动前映射网络共享盘 |
4.3 各参数详细说明
<id>(必填)
Windows 内部用于标识服务的 ID。必须在整个系统中唯一,且应仅由字母和数字组成。
<id>myapp</id>
<executable>(必填)
要启动的可执行程序。可以是绝对路径,也可以只写程序名让系统从 PATH 中搜索。
⚠️ 注意:服务通常运行在不同的用户账户下,其
PATH可能与你的命令行环境不同。
<executable>java</executable>
<!-- 或绝对路径 -->
<executable>C:\Program Files\MyApp\myapp.exe</executable>
<name>(可选)
服务的简短显示名称,可以包含空格等字符。同样需要在系统中唯一,且不宜过长。
<name>My Application Service</name>
<description>(可选)
服务的详细可读描述,会显示在 Windows 服务管理器中。
<description>这是我的应用服务,负责处理后台任务。</description>
<startmode>(可选)
服务启动模式,可选值:Automatic(自动,默认)或 Manual(手动)。
<startmode>Automatic</startmode>
<delayedAutoStart>(可选)
布尔值。在 Automatic 模式下启用"延迟自动启动",让服务在系统启动后延迟一段时间再启动,减轻开机压力。
⚠️ Windows 7 / Server 2008 之前的旧系统不支持,可能导致安装失败。
<delayedAutoStart>true</delayedAutoStart>
<depend>(可选,可重复)
指定本服务依赖的其他服务 ID。若服务 X 依赖服务 Y,则只有 Y 运行时 X 才能运行。可写多个 <depend> 元素表示多个依赖。
<depend>Eventlog</depend>
<depend>W32Time</depend>
<arguments>(可选)
传给可执行程序的命令行参数,可单行书写,也可多行书写。
<arguments>arg1 arg2 arg3</arguments>
或:
<arguments>
arg1
arg2
arg3
</arguments>
<stoparguments> / <stopexecutable> / <startarguments>(可选)
默认情况下,停止服务时 WinSW 直接终止进程。若指定了 <stoparguments>,WinSW 会改为启动另一个进程(默认使用 <executable>,若指定了 <stopexecutable> 则使用它)并传入这些参数,由该进程负责优雅地关闭主服务进程。WinSW 会等待两个进程都自行退出后,才向 Windows 报告服务已终止。
⚠️ 重要:使用
<stoparguments>时,必须用<startarguments>替代<arguments>。
完整示例(Tomcat 风格):
<executable>catalina.sh</executable>
<startarguments>jpda run</startarguments>
<stopexecutable>catalina.sh</stopexecutable>
<stoparguments>stop</stoparguments>
<stoptimeout>(可选)
服务被请求停止时,WinSW 会先向控制台程序发送 Ctrl+C 信号(或向窗口程序发送关闭消息),然后等待最多 15 秒让进程自行优雅退出;超时或信号发送失败时,WinSW 才会强制终止进程。本元素用于修改这个等待时间。
时间单位后缀支持:sec / secs / min / mins / hour / hours / day / days。
<stoptimeout>10sec</stoptimeout>
附加命令:<prestart> / <poststart> / <prestop> / <poststop>(可选)
在服务生命周期的不同阶段执行附加命令:
| 元素 | 执行时机 |
|---|---|
<prestart> |
服务启动时、主进程启动之前 |
<poststart> |
服务启动时、主进程启动之后 |
<prestop> |
服务停止时、主进程停止之前 |
<poststop> |
服务停止时、主进程停止之后 |
每个元素内可包含以下子元素:
<prestart>
<executable>初始化脚本路径</executable>
<arguments>参数</arguments>
<stdoutPath>标准输出重定向路径</stdoutPath>
<stderrPath>标准错误重定向路径</stderrPath>
</prestart>
stdoutPath / stderrPath 指定为 NUL 可丢弃对应的输出流。
<preshutdown> / <preshutdownTimeout>(可选)
系统关机时给服务更多停止时间。系统默认的 preshutdown 超时为 3 分钟。
<preshutdown>false</preshutdown>
<preshutdownTimeout>3 min</preshutdownTimeout>
<env>(可选,可重复)
为子进程设置环境变量,可指定多次。
<env name="HOME" value="c:\abc" />
<env name="JAVA_OPTS" value="-Xmx512m" />
<workingdirectory>(可选)
指定服务进程的工作目录。默认是配置文件所在目录。
<workingdirectory>C:\application</workingdirectory>
<priority>(可选)
进程调度优先级(类似 Unix 的 nice),可选值(不区分大小写):
idle、belownormal、normal、abovenormal、high、realtime
⚠️ 设置高于 normal 的优先级可能产生意外后果。本功能主要用于以较低优先级运行进程,避免干扰交互式使用。
<priority>idle</priority>
<hidewindow>(可选)
设为 true 时,WinSW 以 CreateNoWindow=true 启动进程,防止创建控制台窗口(避免启动时窗口一闪而过)。默认 false。
<hidewindow>true</hidewindow>
<interactive>(可选)
允许服务与桌面交互(显示窗口和对话框)。
⚠️ 自 Windows Vista 引入 UAC 后,服务实际上已不允许直接与桌面交互;在这些系统上该选项只允许用户切换到单独的窗口工作站与服务交互。
<interactive>true</interactive>
<beeponshutdown>(可选)
服务关闭时发出简单提示音。仅用于调试,部分系统和硬件不支持。
<beeponshutdown>true</beeponshutdown>
<onfailure>(可选,可重复)
控制 WinSW 启动的进程异常退出(非零退出码)时的行为。每个元素包含:
action属性(必填),可选值:restart:重启服务reboot:重启 Windows(会显示 CRITICAL_PROCESS_DIED 蓝屏)none:什么都不做,保持服务停止状态
delay属性(可选):执行动作前的延迟,默认 0。时间后缀同<stoptimeout>。
<onfailure action="restart" delay="10 sec"/>
<onfailure action="restart" delay="20 sec"/>
<onfailure action="reboot" />
上例含义:第一次失败 10 秒后重启,第二次失败 20 秒后重启,第三次失败则重启 Windows。失败次数超过配置数量后,重复执行最后一个动作。因此若只想"总是自动重启",写一条即可:
<onfailure action="restart" />
<resetfailure>(可选)
控制 Windows SCM 重置失败计数的时机。例如设为 1 hour,则服务连续运行超过 1 小时后失败计数归零(影响 <onfailure> 的行为)。默认 1 天。
<resetfailure>1 hour</resetfailure>
<download>(可选,可重复)
服务启动时、主程序运行之前,从 URL 下载资源到本地文件。常用于构建自更新服务。
属性列表:
| 属性 | 说明 |
|---|---|
from |
下载源 URL |
to |
保存到的本地路径 |
failOnError |
布尔值,默认 false。设为 true 时下载失败会导致服务启动失败 |
proxy |
自定义代理:http://HOST:PORT/ 或带凭据 http://USERNAME:PASSWORD@HOST:PORT/ |
auth |
认证方式:none(默认,无需指定)/ sspi(Windows SSPI,含 Kerberos、NTLM 等)/ basic(基本认证) |
user |
basic 认证的用户名 |
password |
basic 认证的密码 |
unsecureAuth |
默认 false。仅在 HTTP(非加密)传输时生效——凭据将以明文发送,有安全风险 |
<download from="http://example.com/some.dat" to="%BASE%\some.dat" />
<download from="http://example.com/some.dat" to="%BASE%\some.dat" failOnError="true"/>
<download from="http://example.com/some.dat" to="%BASE%\some.dat" proxy="http://192.168.1.5:80/"/>
<download from="https://example.com/some.dat" to="%BASE%\some.dat" auth="sspi" />
<download from="https://example.com/some.dat" to="%BASE%\some.dat" failOnError="true"
auth="basic" user="aUser" password="aPassw0rd" />
补充说明:
- HTTPS 下载要求客户端信任服务器证书的 CA;企业自签 CA 需先导入到"受信任的根证书颁发机构"。
- 自 2.7 版本起,若目标文件已存在,WinSW 会发送
If-Modified-Since头,收到304 Not Modified时跳过下载。
<serviceaccount>(可选)
服务默认以 LocalSystem 账户安装。如果服务不需要高权限,建议改用 LocalService、NetworkService 或普通用户账户。
使用用户账户:
<serviceaccount>
<username>DomainName\UserName</username>
<password>Pa55w0rd</password>
<allowservicelogon>true</allowservicelogon>
</serviceaccount>
<username>格式:DomainName\UserName或UserName@DomainName;本机内置账户可写.\UserName<allowservicelogon>(可选):设为true时自动为该账户授予"作为服务登录"权限
使用组托管服务账户(gMSA):账户名后加 $ 并移除 <password>:
<serviceaccount>
<username>DomainName\GmsaUserName$</username>
<allowservicelogon>true</allowservicelogon>
</serviceaccount>
使用系统内置账户(这些账户没有密码,提供的密码会被忽略):
<!-- LocalSystem -->
<serviceaccount>
<username>LocalSystem</username>
</serviceaccount>
<!-- LocalService -->
<serviceaccount>
<username>NT AUTHORITY\LocalService</username>
</serviceaccount>
<!-- NetworkService -->
<serviceaccount>
<username>NT AUTHORITY\NetworkService</username>
</serviceaccount>
交互式提示输入凭据:
<serviceaccount>
<prompt>dialog</prompt> <!-- dialog:对话框提示;console:控制台提示 -->
</serviceaccount>
<securityDescriptor>(可选)
以 SDDL(安全描述符定义语言)形式指定服务的安全描述符字符串。
<securityDescriptor>SDDL字符串</securityDescriptor>
<autoRefresh>(可选)
服务启动或执行 start / stop / restart 命令时,自动刷新服务属性。默认 true。
<autoRefresh>true</autoRefresh>
<sharedDirectoryMapping>(可选)
Windows 默认不会为服务建立共享盘映射(即使服务配置文件中配置了)。本元素允许在启动可执行程序前映射外部共享目录。
<sharedDirectoryMapping>
<map label="N:" uncpath="\\UNC" />
<map label="M:" uncpath="\\UNC2" />
</sharedDirectoryMapping>
五、日志配置详解(<log> 与 <logpath>)
WinSW 支持多种方式捕获被启动进程的 stdout 和 stderr。
<logpath> — 日志目录
指定日志文件的创建目录。若不指定,默认为配置文件所在目录。
<logpath>%BASE%\logs</logpath>
日志模式(<log mode="...">)
日志文件名以可执行文件 / 配置文件的基本名命名(下文以 myapp 为例)。
1. append — 追加模式(默认)
创建 myapp.out.log 和 myapp.err.log,输出持续追加。注意文件可能变得很大。
<log mode="append"/>
2. reset — 重置模式
与追加模式类似,但每次服务启动时清空旧日志文件。
<log mode="reset"/>
3. none — 忽略模式
直接丢弃 stdout 和 stderr,完全不生成日志文件。
<log mode="none"/>
4. roll-by-size — 按大小滚动
文件超过设定大小后滚动为 myapp.1.out.log、myapp.2.out.log……
<sizeThreshold>:滚动阈值,单位 KB,默认 10MB<keepFiles>:保留的滚动文件数量,默认 8
<log mode="roll-by-size">
<sizeThreshold>10240</sizeThreshold>
<keepFiles>8</keepFiles>
</log>
README 示例中的
<log mode="roll">即滚动模式的简写形式(滚动为 *.old 文件)。
5. roll-by-time — 按时间滚动
以时间周期为滚动阈值。必须搭配 <pattern> 元素,指定用作日志文件名的时间戳格式(语法遵循 .NET 的 DateTime.ToString(String))。可选的 <keepFiles> 指定保留数量,超限自动删除最旧文件;省略则不删除。
<log mode="roll-by-time">
<pattern>yyyyMMdd</pattern>
<keepFiles>30</keepFiles>
</log>
例如上例中,2013 年 1 月 1 日的日志会写入 myapp.20130101.out.log 和 myapp.20130101.err.log。
6. roll-by-size-time — 按大小和时间组合滚动
结合两种模式:文件超过设定大小时按 <pattern> 滚动;<autoRollAtTime> 指定每天定时滚动的时间点(语法遵循 .NET 的 TimeSpan.ToString(String))。
<log mode="roll-by-size-time">
<sizeThreshold>10240</sizeThreshold>
<pattern>yyyyMMdd</pattern>
<autoRollAtTime>00:00:00</autoRollAtTime>
</log>
日志自动归档(⚠️ 已知在近期版本中损坏,可能被移除)
<zipOlderThanNumDays>:压缩归档超过 N 天的日志文件,必须配合autoRollAtTime使用<zipDateFormat>:归档 zip 文件名的日期格式,同样必须配合autoRollAtTime使用
<log mode="roll-by-size-time">
<autoRollAtTime>00:00:00</autoRollAtTime>
<zipOlderThanNumDays>5</zipOlderThanNumDays>
<zipDateFormat>yyyyMM</zipDateFormat>
</log>
错误报告
- WinSW 成功时退出码为 0,任何正数退出码均为 Windows 系统错误码。
- 以服务方式运行时,更详细的错误信息会写入 Windows 事件日志(事件查看器中可查看)。
六、完整配置示例模板
下面是一个综合了常用配置项的完整模板,可按需删减:
<service>
<!-- ===== 基本信息(id 和 executable 必填) ===== -->
<id>myapp</id>
<name>My Application</name>
<description>我的后台应用服务</description>
<!-- ===== 可执行程序与参数 ===== -->
<executable>%BASE%\myapp.exe</executable>
<arguments>--port 8080 --config "%BASE%\config.json"</arguments>
<workingdirectory>%BASE%</workingdirectory>
<!-- ===== 环境变量 ===== -->
<env name="APP_HOME" value="%BASE%"/>
<env name="APP_ENV" value="production"/>
<!-- ===== 启动方式 ===== -->
<startmode>Automatic</startmode>
<delayedAutoStart>true</delayedAutoStart>
<depend>Eventlog</depend>
<!-- ===== 进程行为 ===== -->
<priority>normal</priority>
<hidewindow>true</hidewindow>
<stoptimeout>20 sec</stoptimeout>
<!-- ===== 失败自动重启策略 ===== -->
<onfailure action="restart" delay="10 sec"/>
<onfailure action="restart" delay="30 sec"/>
<resetfailure>1 hour</resetfailure>
<!-- ===== 日志:按大小滚动,单文件 10MB,保留 8 个 ===== -->
<logpath>%BASE%\logs</logpath>
<log mode="roll-by-size">
<sizeThreshold>10240</sizeThreshold>
<keepFiles>8</keepFiles>
</log>
<!-- ===== 服务账户(默认 LocalSystem,按需取消注释) ===== -->
<!--
<serviceaccount>
<username>NT AUTHORITY\NetworkService</username>
</serviceaccount>
-->
</service>
七、实用提示与常见坑
<id>必须全系统唯一且只能用字母数字;改了 id 等于换了一个服务,需要先卸载旧的。- PATH 差异:服务账户的
PATH与你的终端不同,<executable>尽量写绝对路径或用%BASE%。 - 优雅停止:默认只等 15 秒,对需要较长清理时间的应用(如数据库、JVM 应用)记得调大
<stoptimeout>。 <stoparguments>与<arguments>互斥:用了 stoparguments 就必须把 arguments 改为<startarguments>。- 修改配置后:可用
refresh命令刷新部分服务属性,不必每次都卸载重装;v3 中<autoRefresh>默认开启,start/stop/restart 时也会自动刷新。 - 日志膨胀:默认 append 模式日志会无限增长,生产环境建议用 roll-by-size 或 roll-by-size-time。
- 权限:install/uninstall/start/stop 等命令需要管理员权限;密码等敏感信息写入 XML 时注意文件访问权限,或考虑 gMSA / prompt 方式。
- 版本差异:本文基于 v3 分支文档;如果你使用的是 2.x 稳定版,部分细节请参考仓库的 v2 分支文档。
参考链接
- 仓库主页:https://github.com/winsw/winsw
- XML 配置规范:https://github.com/winsw/winsw/blob/v3/docs/xml-config-file.md
- CLI 命令文档:https://github.com/winsw/winsw/blob/v3/docs/cli-commands.md
- 日志与错误报告:https://github.com/winsw/winsw/blob/v3/docs/logging-and-error-reporting.md
- 配置示例:https://github.com/winsw/winsw/tree/v3/samples
- 下载发布版:https://github.com/winsw/winsw/releases