案例
此处以nginx.exe
实现服务化为例子,nginx.exe
所在目录为D:\Program Files\nginx-1.21.1
,nginx.conf
配置文件内容如下,访问端口为7080
.....省略...... http { .....省略...... server { listen 7080; server_name localhost; location / { root html; index index.html index.htm; } .....省略...... } }
以管理员身份启动cmd
,执行如下指令,否则将执行指令失败,提示You are not authorized to do this - please contact your system Administrator
,意思是当前账户没有权限执行这个服务操作,需要管理员权限
>instsrv nginx "C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe" The service was successfuly added! Make sure that you go into the Control Panel and use the Services applet to change the Account Name and Password that this newly installed service will use for its Security Context.
查询服务
方式一
sc query nginx SERVICE_NAME: nginx TYPE : 10 WIN32_OWN_PROCESS STATE : 1 STOPPED WIN32_EXIT_CODE : 1077 (0x435) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0
方式二
打开【任务管理器】-【服务】,可以查找到一个名为nginx
的服务,当前状态为停止状态
方式三
查看注册表
执行regedit.exe
,查看注册表,查找对应注册清单中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[servicename]
(此处为nginx
)对应的ImagePath
是否为C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe
如果是,则表示,服务注册成功
配置服务[修改前先导出备份]
备份
服务注册成功之后,需要进行对应的服务程序配置,由于注册表配置属于比较危险的操作,配置错误有可能影响到系统的正常使用,修改前,先对目标nginx
进行导出备份处理,操作如下,【选中nginx
节点】-单击右键【导出】特定位置保留一个xxx.reg
文件,此处设置为nginx.reg
添加配置
在nginx
节点下,添加项
,名称为Parameters
之后在Parameters
下添加几个字符串值
AppDirectory
表示服务运行的工作目录
Application
表示服务程序对应的物理地址
AppParameters
表示服务运行携带的默认参数,默认为空值
结果如下:
启动服务
方式一
配置好之后,尝试通过管理员权限运行cmd
,进行服务nginx
的运行
>sc start nginx SERVICE_NAME: nginx TYPE : 10 WIN32_OWN_PROCESS STATE : 2 START_PENDING (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x7d0 PID : 72712 FLAGS : >sc query nginx SERVICE_NAME: nginx TYPE : 10 WIN32_OWN_PROCESS STATE : 4 RUNNING (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0
方式二
执行net start [servicename]
进行服务启动
>net start nginx nginx 服务正在启动 . nginx 服务已经启动成功。
查找进程
查看实际系统中启动的对应服务所属应用进程
>tasklist /fi "imagename eq nginx.exe" 映像名称 PID 会话名 会话# 内存使用 ========================= ======== ================ =========== ============ nginx.exe 68272 Services 0 17,892 K nginx.exe 67928 Services 0 18,204 K
浏览器访问http://localhost:7080
,出现如下结果,表示服务启动成功
停止服务
方式一
使用sc stop [servicename]
>sc stop nginx SERVICE_NAME: nginx TYPE : 10 WIN32_OWN_PROCESS STATE : 1 STOPPED WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0
方式二
使用net stop [servicename]
>net stop nginx nginx 服务正在停止.
查看进程
服务正常停止时,查看结果
>tasklist /fi "imagename eq nginx.exe" 信息: 没有运行的任务匹配指定标准。
此处nginx
属于多进程,结束服务自后,实际上本地还有进程并未完全退出
>tasklist /fi "imagename eq nginx.exe" 映像名称 PID 会话名 会话# 内存使用 ========================= ======== ================ =========== ============ nginx.exe 38432 Services 0 17,876 K
方式三
执行任务结束指令taskkill /T /F /IM [appname]
>taskkill /T /F /IM nginx.exe 成功: 已终止 PID 56132 (属于 PID 70920 子进程)的进程。 成功: 已终止 PID 70920 (属于 PID 74512 子进程)的进程。 成功: 已终止 PID 74512 (属于 PID 67556 子进程)的进程。
注意
需要注意的是,方式一
和方式二
停止服务,比较适合单进程应用程序,如果对应服务化的程序为多进程程序,改方式仅仅只能停止部分进程,例如当前案例nginx
以此种方式就无法彻底结束所有进程,如果非要全部退出,可以直接使用方式三
,虽然粗暴,但是确实使用,能够满足结束服务的需求
卸载服务
方式一
使用instsrv [servicename] remove
>instsrv nginx remove The service was successfully deleted!
方式二
使用sc delete [servicename]
>sc delete nginx [SC] DeleteService 成功
总结
笔者简单的通过本地安装rktools.exe
去获取到对应的instsrv.exe
和srvany.exe
,依靠这俩工具,实现本地不遵循Windows
服务化规范的应用程序拟态
(个人认为这不属于实际的应用服务化,而是对服务化状态进行模拟实现的折中功能)服务化,对应用的操作逐渐接近实现本质,如果想继续了解服务化内容,可关注笔者留言评论或私信
参考链接
【1】https://zhuanlan.zhihu.com/p/93808282
【2】https://wangye.org/blog/archives/42/
【3】https://www.cnblogs.com/zhaiqianfeng/p/4622561.html
【4】https://gist.github.com/eyecatchup/0107bab3d92473cb8a3d3547848fc442
【5】https://docs.microsoft.com/zh-cn/troubleshoot/windows-client/deployment/create-user-defined-service