我们知道,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. 参考资料
- https://www.cnblogs.com/findumars/p/5811646.html
- https://support.microsoft.com/en-us/help/137890/how-to-create-a-user-defined-service
- https://www.technlg.net/windows/download-windows-resource-kit-tools/
- http://www.nssm.cc/usage
title: Windows上使用NSSM将进程注册为服务保持常开
time: 2018-05-25 20:44
tags: Windows,守护进程,NSSM
category: Study
想想你的文章写的特别好
想想你的文章写的特别好https://www.237fa.com/