WinSW (Windows服务包装器),可以将任何应用程序作为 Windows 服务进行包装和管理。
项目开源地址:链接地址
WinSW核心为xml配置文件,可以自定义很多配置,如:jar启动参数、引用环境变量、启动停止服务时引用外部脚本文件、文件下载、外部共享目录映射等,我这里的脚本只对日志存储做了自定义,更多的xml属性参阅官网说明:xml文件说明地址
由于WinSW支持命令操作,为了方便,我这里编写了一个bat脚本菜单操控WinSW
用法:下载WinSW-x64.exe并将以下脚本拷贝保存为.bat文件与WinSW-x64.exe放置到同一目录,启动bat脚本即可使用;该脚本会按照jar名称生成对应的WinSW xml配置和服务
如果想在powershell代码块中获取bat文件中定义的变量,可以使用 “$env:变量名” 获取:
第一版达到了效果,但是不太美观,更新了一版:
<# :
REM WinSW 开源地址: https://github.com/winsw/winsw?tab=readme-ov-file
@echo off
SetLocal EnableDelayedExpansion
chcp 65001
set "jarFilePath="
set "jarFileName="
set "currentDir=%~dp0"
:checkFileExistence
if "%2" == "call" (
timeout /t 1 > nul
echo 检测必要文件是否存在...
IF EXIST "%~1" (
echo true
echo.
) else (
timeout /t 1 > nul
echo 必要文件 %~1 不存在,无法执行,请检查...
call :gotoMenu call
)
goto :eof
)
:gotoMenu
if "%1" == "call" (
timeout /t 2 > nul
echo.
echo 按任意键返回菜单
pause
goto menu
)
:generateXML
if "%1" == "call" (
(
echo ^<service^>
echo ^<id^>!jarFileName!^</id^>
echo ^<name^>!jarFileName!^</name^>
echo ^<description^>自定义Windows服务包装器-!jarFileName!-Jar服务^</description^>
echo ^<executable^>java^</executable^>
echo ^<arguments^>-jar "!jarFilePath!"^</arguments^>
echo ^<logpath^>serviceLogs/^</logpath^>
echo ^<log mode="roll-by-time"^>
echo ^<pattern^>yyyyMMdd^</pattern^>
echo ^<sizeThreshold^>10240^</sizeThreshold^>
echo ^<keepFiles^>15^</keepFiles^>
echo ^</log^>
echo ^<onfailure action="restart" /^>
echo ^</service^>
) > !jarFileName!.xml
goto :eof
)
echo ************************************
echo * Jar Windows服务安装脚本V2.0 *
echo ************************************
echo.
timeout /t 2 > nul
echo 请按照提示执行操作......
timeout /t 1 > nul
echo 请选择一个Jar文件:
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
echo 你选择的Jar文件路径: %%~I
echo 即将跳转操作菜单...
set "jarFilePath=%%~I"
timeout /t 3 > nul
)
for %%F in ("!jarFilePath!") do set "jarFileName=%%~nF"
:menu
cls
echo ************************************
echo * 服务操作菜单 *
echo ************************************
echo ------------------------
echo "1: 安装服务"
echo "2: 卸载服务"
echo "3: 启动服务"
echo "4: 停止服务"
echo "5: 重启服务"
echo "6: 刷新服务"
echo "7: 服务状态"
echo "8: 退出"
echo ------------------------
set /p choice=请输入操作对应的数字:
if "%choice%"=="1" goto install
if "%choice%"=="2" goto uninstall
if "%choice%"=="3" goto start
if "%choice%"=="4" goto stop
if "%choice%"=="5" goto restart
if "%choice%"=="6" goto refresh
if "%choice%"=="7" goto status
if "%choice%"=="8" goto exit
:install
call :checkFileExistence "%currentDir%WinSW-x64.exe" call
echo WinSW-x64.exe文件存在,重命名为待安装的服务:!jarFileName!.exe...
ren "%currentDir%WinSW-x64.exe" "!jarFileName!.exe"
echo 正在生成配置文件...
call :generateXML call
echo 正在安装服务...
"%currentDir%!jarFileName!".exe install
echo.
call :start
call :gotoMenu call
:uninstall
echo 正在卸载服务...
call :checkFileExistence "%currentDir%!jarFileName!.exe" call
call :checkFileExistence "%currentDir%!jarFileName!.xml" call
"%currentDir%!jarFileName!".exe stop
"%currentDir%!jarFileName!".exe uninstall
set /p choice=是否删除服务相关文件(日志目录、xml文件、WinSW-x64程序)? (Y/N):
if /i "%choice%"=="Y" (
del %currentDir%!jarFileName!.exe
del %currentDir%!jarFileName!.xml
rmdir /s /q %currentDir%!serviceLogs
) else (
ren "!jarFileName!.exe" "WinSW-x64.exe"
)
call :gotoMenu call
:start
echo 正在启动服务...
call :checkFileExistence "%currentDir%!jarFileName!.exe" call
call :checkFileExistence "%currentDir%!jarFileName!.xml" call
"%currentDir%!jarFileName!".exe start
call :gotoMenu call
:stop
echo 正在停止服务...
call :checkFileExistence "%currentDir%!jarFileName!.exe" call
call :checkFileExistence "%currentDir%!jarFileName!.xml" call
"%currentDir%!jarFileName!".exe stop
call :gotoMenu call
:restart
echo 正在重启服务...
call :checkFileExistence "%currentDir%!jarFileName!.exe" call
call :checkFileExistence "%currentDir%!jarFileName!.xml" call
"%currentDir%!jarFileName!".exe restart
call :gotoMenu call
:refresh
echo 正在刷新服务...
call :checkFileExistence "%currentDir%!jarFileName!.exe" call
call :checkFileExistence "%currentDir%!jarFileName!.xml" call
"%currentDir%!jarFileName!".exe refresh
call :gotoMenu call
:status
echo 正在读取服务状态...
call :checkFileExistence "%currentDir%!jarFileName!.exe" call
call :checkFileExistence "%currentDir%!jarFileName!.xml" call
"%currentDir%!jarFileName!".exe status
call :gotoMenu call
:exit
echo 退出菜单...
timeout /t 1 > nul
exit
: end Batch portion / begin PowerShell hybrid chimera #>
Add-Type -AssemblyName System.Windows.Forms
$f = new-object Windows.Forms.OpenFileDialog
$f.InitialDirectory = pwd
$f.Filter = "Jar Files (*.jar)|*.jar|All Files (*.*)|*.*"
$f.ShowHelp = $true
$f.Multiselect = $true
[void]$f.ShowDialog()
if ($f.Multiselect) { $f.FileNames } else { $f.FileName }