在windows系统实现进程守护,自动重启意外退出的程序

在windows系统上实现守护某个exe进程或jar进程,如果进程意外退出,自动启动

本文最新修改于2025年12月13日

背景

我们写的软件需要调用一个第三方的厂商的硬件,第三方厂商提供了一个 websocket 的服务部署在 windows 系统上,我们的软件通过与这个 websocket 服务通信来调用第三方硬件。所以这个 websocket 程序一定不能挂掉,否则我们的软件也就出问题了。但是事与愿违,这个 websocket 程序经常莫名其妙的挂掉了,经过观察,有可能是写的不好,CPU 占用有时会很高,被系统干掉了。

所以守护这个 websocket 程序是至关重要。

除此之外,我们常常会把jar包部署在客户的windows上,虽然可以直接用cmd启动jar,或者直接写一个bat脚本来启动,但这种方式肯定不如使用windows服务。

windows服务

windows 系统服务的注册可以使用 sc 命令

sc.exe [<servername>] create [<servicename>] 
[type= {own | share | kernel | filesys | rec | interact type= {own | share}}] 
[start= {boot | system | auto | demand | disabled | delayed-auto}] 
[error= {normal | severe | critical | ignore}] 
[binpath= <binarypathname>] 
[group= <loadordergroup>] 
[tag= {yes | no}] 
[depend= <dependencies>] 
[obj= {<accountname> | <objectname>}] 
[displayname= <displayname>] 
[password= <password>]

但有两个问题:

1、直接使用 exe 程序创建出来的服务可能不能启动!

如果被封装的 .exe 程序不是原生 Windows 服务(即不支持 Service Control Protocol, SCP),则 SCM 无法与其正常通信,可能导致:

  • 服务启动后立即退出;
  • SCM 报错:“服务没有及时响应启动或控制请求”(错误 1053)

因此,对于普通 GUI 程序或批处理脚本,直接用 sc create 注册往往不可靠

2、服务意外退出是不能自动重启的

sc.exe create 命令本身仅负责将服务注册到服务控制管理器(SCM)中,并不自动设置崩溃后的自动恢复行为。

如果服务进程因异常崩溃或被终止,SCM 不会主动重新启动它,服务状态将停留在“已停止”,除非手动干预或系统重启(若为 auto 启动类型)。

要实现“意外退出后自动重启”,需要额外配置服务的 恢复策略(Recovery Policy)

  • 方式1:使用 sc failure 命令配置恢复动作
  • 方式2:通过服务属性图形界面设置
    • 打开 services.msc
    • 右键目标服务 → “属性” → “恢复”选项卡;
    • 设置“第一次失败”、“第二次失败”、“后续失败”的操作为“重新启动服务”;
    • 设置“重置失败计数”为 300 秒(或其他合适值)

NSSM

NSSM (Non-Sucking Service Manager)是一款专为Windows系统设计的开源工具,可将普通可执行程序(如exe、批处理脚本、Python/Node.js应用等)注册为系统服务,实现后台静默运行、开机自启动、崩溃自动重启和日志管理等功能。

官方文档 https://nssm.cc/usage

  • 下载 NSSM

  • 打开命令提示符cmd(以管理员身份运行),然后切换至NSSM所在的目录

  • 运行 nssm.exe install,会立即弹出一个对话框

  • 在弹出的对话框中完成设置,一般来说:

    • 设置服务名称
    • 选择程序的运行目录
    • 选择要运行的程序
    • 设置启动命令行参数
    • 设置退出重启
    • 设置输出重定向到文件(日志)
    • 最后点击 install service
  • 服务注册完成后,可以通过 windows 上的服务功能中找到,并可以启动;也可以使用nssm start <服务名>启动服务