前言
优雅,实在是太优雅了,作为一个 被微信拖累而 迟迟转不到 Linux 的 Windows 用户,有些 Linux 下常用的在 Windows 下很难找到替代,就比如 Systemctl,我虽然可以用 Windows 任务计划程序
来实现自启动,但是终究不能快速调试,不够优雅,不合习惯。
介绍
WinSW (Windows Service Wrapper) 是一个开源工具,主要用于将任何可执行文件(例如Java程序、批处理脚本等)包装成Windows服务,使其能够像本机服务一样运行和管理。它提供了一种简单的方法来创建和管理自定义的Windows服务,适合需要在Windows环境中以服务形式运行应用程序的情况。
——ChatGPT 4o
这个工具可以通过编写 XML 文件把 exe 运行文件打包成系统服务,然后通过命令启停等等。着实是一个完美的 Windows Systemctl,可以完美替代我之前写的
使用
下载
点击WinSW-x64.exe
使用
官方提供了两种使用方法,一种是作为全局工具使用,一种是作为捆绑工具,供单个应用使用。
全局工具
从 Github 下载 WinSW-x64.exe,重命名为 winsw.exe。
将 winsw.exe 添加到环境变量。
编写 myapp.xml(XML 配置文件编写规范)。
运行
winsw install myapp.xml [options]
以安装服务。运行
winsw start myapp.xml
以启动服务。运行
winsw status myapp.xml
以查看服务状态。
捆绑工具
从 Github 下载 WinSW-x64.exe,然后根据喜好重命名(例如
myapp.exe
)。编写 myapp.xml(XML 配置文件编写规范)。
将
myapp.exe
和myapp.xml
放置到同一文件夹下。运行
myapp.exe install [options]
以安装服务。运行
myapp.exe start
以启动服务。运行
winsw status
以查看服务状态。
XML 配置文件
文件规范
<service>
<!-- ID[必需]: 指定服务 ID。此 ID 在系统中安装的所有服务中必须是唯一的,并且应完全由字母数字字符组成。-->
<id>Sing-box</id>
<!-- Name[可选]: 指定服务的显示名称,在系统中安装的所有服务中必须是唯一的。 -->
<name>Jenkins</name>
<!-- 描述[可选] -->
<description>该服务是Jenkins服务</description>
<!-- 启动模式[可选]: 指定服务的启动模式。Automatic(自动,默认) 或 Manual(手动) -->
<startmode>Automatic</startmode>
<!-- 延迟自动启动[可选]: 指定服务是否延迟启动。true 或 false -->
<delayedAutoStart>false</delayedAutoStart>
<!-- 依赖项[可选]: 指定服务的依赖项。 -->
<depend></depend>
<!-- 工作目录[可选]: 指定服务的工作目录。 -->
<workingdirectory>D:\</workingdirectory>
<!-- 可执行文件[必须]: 指定要启动的可执行文件。可以是绝对路径,也可以是环境变量中指定的可执行文件。-->
<executable>java</executable>
<!-- 环境变量[可选]: 指定要传递给可执行文件的环境变量。 -->
<env name="JENKINS_HOME" value="%BASE%"/>
<!-- 参数[可选]: 指定要传递给可执行文件的参数。 -->
<arguments>arg1 arg2 arg3</arguments>
<!-- 停止参数/停止命令[可选]: 指定停止服务时要传递给可执行文件的参数,当使用<stoparguments>时,必须使用<startarguments>替换<arguments> -->
<executable>catalina.sh</executable>
<startarguments>jpda run</startarguments>
<stopexecutable>catalina.sh</stopexecutable>
<stoparguments>stop</stoparguments>
<!-- 其他命令[可选]: 指定其他命令。 -->
<!-- 预启动命令在服务启动时,主进程启动之前执行。 -->
<prestart>
<executable></executable>
<arguments></arguments>
<stdoutPath></stdoutPath>
<stderrPath></stderrPath>
</prestart>
<!-- 后启动命令在服务启动时,主进程启动完成后执行。 -->
<prestop>
<executable></executable>
<arguments></arguments>
<stdoutPath></stdoutPath>
<stderrPath></stderrPath>
</prestop>
<!-- 预停止命令在服务停止时,主进程停止之前执行。 -->
<poststop>
<executable></executable>
<arguments></arguments>
<stdoutPath></stdoutPath>
<stderrPath></stderrPath>
</poststop>
<!-- 停止超时[可选]: 指定服务停止的超时时间,默认为 Ctrl+C 信号后 15 秒。 -->
<stoptimeout>10sec</stoptimeout>
<!-- 下载文件[可选]: 指定要下载的文件。 -->
<download from="http://example.com/some.dat" to="%BASE%\some.dat"
proxy="http://aUser:aPassw0rd@192.168.1.5:80/"
auth="basic" unsecureAuth="true"
user="aUser" password="aPassw0rd" />
<!-- 日志记录路径[可选]: 指定服务的日志记录路径。若未设置,则默认为配置文件同一目录。 -->
<logpath></logpath>
<!-- 日志记录模式[可选]: append(追加,默认) reset(重置) none(无) roll-by-size(按大小滚动) roll-by-time(按时间滚动) roll-by-size-time(按大小和时间滚动) -->
<log mode="append"/>
<log mode="reset"/>
<log mode="none"/>
<log mode="roll-by-size">
<sizeThreshold>10240</sizeThreshold>
<keepFiles>8</keepFiles>
</log>
<log mode="roll-by-time">
<pattern>yyyyMMdd</pattern>
</log>
<log mode="roll-by-size-time">
<sizeThreshold>10240</sizeThreshold>
<pattern>yyyyMMdd</pattern>
<autoRollAtTime>00:00:00</autoRollAtTime>
</log>
<!-- 失败时重试[可选]: 指定服务启动失败时的重试次数和重试间隔。 -->
<onfailure action="restart" delay="10 sec"/> <!-- 重启服务,delay 可选延迟时间 -->
<onfailure action="reboot" /> <!-- 重新启动 Windows。将显示蓝屏错误代码。 -->
<onfailure action="none" /> <!-- 不执行任何操作,让服务停止 -->
</service>
示例
<service>
<id>sing-box</id>
<name>sing-box</name>
<description>Sing-box Server</description>
<executable>sing-box.exe</executable>
<arguments>run</arguments>
<log mode="none"/>
<onfailure action="restart" />
</service>
用法
winsw install [<path-to-config>] [--no-elevate] [--user|--username <username>] [--pass|--password <password>]