如何创建Windows Service实现JAR开机自动执行?脚本问题与工具咨询
将JAR包作为Windows服务运行的实现指引
一、手动实现的核心问题分析
你当前的PowerShell脚本存在两个致命问题:
- 服务状态更新失效:
SetServiceStatusAPI需要传入服务的合法状态句柄(hServiceStatus),但脚本中使用了无效的[System.IntPtr]::Zero,导致SCM完全无法接收状态更新请求。 - 服务自动终止:Windows服务要求宿主进程持续运行并响应SCM的状态查询,你的脚本启动JAR后没有维持自身进程的存活,SCM检测不到服务进程的响应,就会在5-10分钟后自动终止服务。
本质上,普通PowerShell脚本无法直接作为Windows服务的宿主——Windows服务必须实现SCM规定的协议,包括状态汇报、控制指令响应等,这不是简单的脚本能完成的。
二、第三方工具选型建议
Apache Procrun(优先推荐)
- 属于Apache Commons官方维护项目,安全可靠,专为Java应用设计,适合生产环境部署
- 支持服务的安装/卸载、启动/停止、自动重启,可配置JVM参数、日志路径等细节
- 完全开源免费,社区支持完善
NSSM(非服务管理器)
- 轻量级通用工具,可将任意可执行程序包装成服务
- 操作简单,提供图形化配置界面,适合快速测试或非Java程序
- 开源免费,但更新频率较低,针对Java应用的定制化支持不如Procrun
两者均安全可靠,Java应用优先选择Procrun,通用程序可考虑NSSM。
三、修正后的手动实现方案(仅用于演示,不建议生产使用)
如果坚持手动实现,可通过New-Service创建一个维持进程存活的服务,但仍无法解决状态汇报问题:
$serviceName = "E-invoiceService" $logFilePath = "path\einvoiceServiceInfo.log" $jarPath = "path/e-invoice.jar" function WriteLog { param ( [string] $msg, [string] $logLevel = "INFO" ) $logmsg = "$logLevel - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $msg" Add-Content -Path $logFilePath -Value $logmsg -Force } # 需以管理员权限执行 New-Service -Name $serviceName ` -BinaryPathName "powershell.exe -NoProfile -WindowStyle Hidden -Command `"& { Start-Process java -ArgumentList '-jar','$jarPath' -NoNewWindow; while ($true) { Start-Sleep -Seconds 60; WriteLog 'Service heartbeat...' } }`"" ` -DisplayName "E-invoice Service" ` -Description "Runs the E-invoice JAR application" ` -StartupType Automatic WriteLog "Service installed successfully."
该方案局限:无法向SCM正确汇报JAR的运行状态,无法响应SCM的停止指令,稳定性差,仅用于临时测试。
四、Procrun标准部署步骤(推荐)
- 下载Apache Commons Daemon的Procrun工具,解压得到
prunsrv.exe和prunmgr.exe - 创建安装脚本
install-service.bat(需管理员权限运行):
@echo off set SERVICE_NAME=E-invoiceService set PR_INSTALL=C:\your-path\prunsrv.exe set PR_DISPLAYNAME=E-invoice Service set PR_DESCRIPTION=Runs the E-invoice JAR application set PR_STARTUP=auto set PR_STARTMODE=jvm set PR_JVM=C:\your-path\java.exe set PR_JVMARGS=-jar "C:\your-path\e-invoice.jar" set PR_STOPMODE=jvm set PR_STOPCLASS=com.yourcompany.Main set PR_STOPMETHOD=stop set PR_LOGPATH=C:\your-path\logs set PR_OUTLOG=%PR_LOGPATH%\service-out.log set PR_ERRLOG=%PR_LOGPATH%\service-err.log %PR_INSTALL% //IS//%SERVICE_NAME% ^ --DisplayName "%PR_DISPLAYNAME%" ^ --Description "%PR_DESCRIPTION%" ^ --Startup "%PR_STARTUP%" ^ --StartMode "%PR_STARTMODE%" ^ --Jvm "%PR_JVM%" ^ --JvmArgs "%PR_JVMARGS%" ^ --StopMode "%PR_STOPMODE%" ^ --StopClass "%PR_STOPCLASS%" ^ --StopMethod "%PR_STOPMETHOD%" ^ --LogPath "%PR_LOGPATH%" ^ --OutLog "%PR_OUTLOG%" ^ --ErrLog "%PR_ERRLOG%" echo Service installed successfully. pause
- 运行脚本完成服务安装,可通过
prunmgr.exe //ES//%SERVICE_NAME%打开图形化界面调整配置
内容的提问来源于stack exchange,提问作者Sai from CDM
相关产品推荐
相关产品推荐

