Windows上使用NSSM将进程注册为服务保持常开

我们知道,Linux中有各种各样的守护进程软件,比如可以使用现代Linux发行版都会带有的Systemd,node项目常用的pm2和forever,py项目常见的supervisord等等,使用起来都十分方便。但是在宇宙第一软件公司巨硬的宇宙第一操作系统Windows,就很蛋疼。工作项目中有个利用OpenOffice提供的word/excel/powerpoint转pdf的功能,需要Openoffice保持以无GUI方式常开提供接口,但是Openoffice不知道中了什么邪,每隔一段时间就会自动退出。尝试多种办法,终于找到一个简单好用的守护进程工具NSSM。遂记录如下。

1. 环境

  • Windows Server 2012 x86_64 Standard Edition

2. 失败的方案

2.1. 手写“守护进程”

我确定问题出在Openoffice总是进程自己终止后,第一反应就是写个守护进程。其实我早在大二参加挑战杯做《基于RSA算法的软件授权保护平台》这一项目的时候,就用VC6写过一个“守护进程”保证授权验证进程持续运行,但是参加这种比赛显然是充满了水分的,实际上实现的原理仅仅是寻找当前有没有特定进程名的进程,并不是真正的守护进程!真正的守护进程学过APUE都明白。这次我又照葫芦画瓢,从网上找了个批处理按自己的需求改了改,代码:

@echo off

set _processName=soffice.exe
set _command="soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard"
set _des=start.bat

:checkifisrunning
for /f "tokens=5" %%n in ('qprocess.exe ^| find "%_processName%" ') do (
 if %%n==%_processName% (goto stillrunning) else goto restartcmd
)

:startcmd
echo %time% 
echo ---Going to Restart--
echo start %_command% > %_des%
echo exit >> %_des%
start %_des%
echo Wscript.Sleep WScript.Arguments(0) > %tmp%\delay.vbs 
cscript //b //nologo %tmp%\delay.vbs 10000 
del %_des% /Q
echo ---Restart Done--
goto checkifisrunning

:stillrunning
echo %time% Still Running, Re-check after 10 seconds.. 
echo Wscript.Sleep WScript.Arguments(0) > %tmp%\delay.vbs 
cscript //b //nologo %tmp%\delay.vbs 10000 
goto checkifisrunning

在此必须吐槽一下批处理,巨硬哪个弱智发明的bat语法,吃翔去吧。学过bat的可以看看,没学过bat的建议直接扔了这玩意,我们有一万种替代bat的脚本语言。
运行倒是没什么问题,但是很快就出现了无法接受的地方:远程桌面关闭后这玩意居然暂停运行了。我也懒得研究bat到底怎么纯后台运行了,我有那功夫还不如换个办法。

2.2. MS的又一垃圾:initsrv和srvany

转念一想,以前配过tomcat,tomcat可以将自己注册为windows的服务运行,这样连进程都找不到了,因为用svchost在跑了。巨硬肯定有一套工具能干这活,于是我开始搜索,结果发现了巨硬的又一垃圾:srvany。

对于srvany,MS有这么一篇文章:https://support.microsoft.com/en-us/help/137890/how-to-create-a-user-defined-service
可以看到最下方,这文章更新于2018年4月,搞的跟很新很实用一样。文章介绍这个initsrv和srvany在Windows NT Resource Kit里,可以将exe注册成服务,但是问题来了,这页面并没有Windows NT Resource Kit的下载地址。因为这是MS的产品,我直接选择了用bing搜索,结果搜索结果很让我吃惊:

这都什么鬼版本,一个2003一个1999年的NT4,然后我又发现一个页面(https://www.technlg.net/windows/download-windows-resource-kit-tools/)告诉我这个Resource Kit吧,2003就是最后一个版本,已经dead了,win7装也能装,会有一堆东 西不能用,对于我的Server 2012提都没提。我心惊胆颤的下载,结果发现还真能用。
具体怎么用就不说了,这玩意垃圾就垃圾在他说他能让exe变成服务,还真只能让exe变成服务,并没有提供守护的作用,并不管进程挂了要不要重启。当我发现我注册好的服务显示正常运行,实际上应该监听的端口根本没东西占时是崩溃的。

3. Windows守护进程救星NSSM

一番搜索后,我发现了NSSM这个软件(http://www.nssm.cc/),其官网标题栏就让我很解气,NSSM表示the Non-Sucking Service Manager。然后第一行介绍该作者就表示:nssm is a service helper which doesn't suck. srvany and other service helper programs suck. 于是我一眼就觉得这货和这货作者肯定吊,靠谱!

下面言归正传介绍下nssm具体使用。

3.1. 介绍

NSSM可以将可执行文件注册为Windows系统服务,并且会监视该进程,失败时会自动重新启动。NSSM作者写道:With nssm you know that if a service says it's running, it really is. :)

NSSM可以运行在Windows2000之后所有版本上,二进制包和源代码下载地址见:
http://www.nssm.cc/download

3.2 使用方法

将nssm解压到任一目录,cmd里运行

nssm install <servicename>

即可自动启动nssm的GUI界面

界面简单易用,选择好exe文件路径和参数,直接Install Service,你的服务就安装完了。以后要启动停止重启删除可以直接在cmd里

nssm start/stop/restart/remove <servicename>

更可以直接在系统服务(services.msc)里修改状态。

如果要修改参数或文件路径

nssm edit <servicename>

即可重新打开GUI。

如果对高级配置有需求,具体每个页面的使用方法请参阅:http://www.nssm.cc/usage

4. WinSW

用winsw将frp注册为系统服务
这个方法最稳定,这是我最终用的方法。
下载winsw https://github.com/kohsuke/winsw/releases ,改名为winsw.exe,放到frp相同的目录里,在同一个目录里创建一个utf8编码的文本文件,文件名是 winsw.xml,内容是:

<service>
    <id>frp</id>
    <name>frp这里是服务的名称</name>
    <description>这里是服务的介绍,随便写</description>
    <executable>frpc</executable>
    <arguments>-c frpc.ini</arguments>
    <onfailure action="restart" delay="60 sec"/>
    <onfailure action="restart" delay="120 sec"/>
    <logmode>reset</logmode>
</service>

以管理员权限打开一个命令窗口,cd到frp所在目录,执行:
winsw install
winsw start

大功告成!

如果要卸载服务,执行命令:
winsw stop
winsw uninstall

5. 参考资料

  1. https://www.cnblogs.com/findumars/p/5811646.html
  2. https://support.microsoft.com/en-us/help/137890/how-to-create-a-user-defined-service
  3. https://www.technlg.net/windows/download-windows-resource-kit-tools/
  4. http://www.nssm.cc/usage

title: Windows上使用NSSM将进程注册为服务保持常开
time: 2018-05-25 20:44
tags: Windows,守护进程,NSSM
category: Study 

标签: Windows 守护进程 NSSM

发表评论: