太阳当空照-Windows服务化方式脚本封装sc指令(下)

简介: 太阳当空照-Windows服务化方式脚本封装sc指令(下)

执行批处理文件

call

参考链接:https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/call

从一个批处理程序调用另一个批处理程序,而不停止父批处理程序,需要注意的是该指令在命令提示符中执行无效

call [drive:][path]<filename> [<batchparameters>] [:<label> [<arguments>]]

[<drive>:][<path>]<filename>需要指定的bat的路径和名称,需要指明批处理文件的文件后缀,name.batname.cmd

<batchparameters>指定批处理程序所需的任何命令行信息

示例:

创建一个child.bat,内容如下:

echo helloworld~

同目录下,再创建一个parent.bat,调用child.bat

@echo off
CHCP 65001
echo 开始调用子批量处理文件
call child.bat 
echo %errorlevel%
echo 完成子批量处理文件
pause

执行parent.bat

>parent.bat
Active code page: 65001
开始调用子批量处理文件
helloworld~
完成子批量处理文件
Press any key to continue . . .

:<label>指定批处理跳转的标签名称

<arguments>指定要传递给批处理程序的新实例(从开始)的命令行信息 :<label>

批处理参数

%~1   展开 %1 并删除周围的引号
%~f1  将 %1 扩展到完全限定的路径

示例:

创建文件callself.bat,文件内容如下,以执行方式跳转标签并传递参数

@echo off
CHCP 65001
call :labelname "参数01"
echo 1
echo 2
if %errorlevel%==1 (
exit /b
)
:labelname
echo 3
echo 4
exit /b 1

输出结果

>callself.bat
Active code page: 65001
3
参数01
4
1
2

定向跳转

goto

cmd.exe定向到批处理程序中带标签的行

参考链接:https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/goto

goto <label>

<label>指定一个文本字符串,该字符串用作批处理程序中的标签

更改当前工作路径

获取当前bat所在路径,切换该路径为工作目录

cd /d %~dp0

实现逻辑

将脚本文件作为一个简单的指令入口,将指令依据实际的操作标识字符串进行访问到对应的子批量处理文件,例如输入install就开始执行安装服务的安装引导,其他操作同理,由于脚本是由多个批处理文件组成,所有批处理结构如下:

判定服务是否存在

查询服务

>sc query servicename

当服务不存在时,输出如下:

>sc query sct
[SC] EnumQueryServicesStatus:OpenService FAILED 1060:
The specified service does not exist as an installed service.

若只是需要获取错误码,则设置输出为nul

>sc query sct >nul
>
>echo %errorlevel%
1060

因此可以采用上述方式对服务是否安装进行判定sc query servicename >nul

创建isexist.bat作为判定服务脚本

@echo off
::CHCP 65001
::判定服务是否存在
set name=%~1
::echo %name%
sc query %name% >nul
exit /b

输入判定

@echo off
::CHCP 65001
::接收外部参数
set option=%~1
:setname
::输入服务名称
set /p servicename=请输入需要%option%的服务名称:
::判定服务名称是否为空
if "%servicename%"=="" (
echo 服务名称不能为空
goto setname
)
call isexist.bat %servicename%
if %errorlevel%==1060 (
echo 服务名称不存在或服务未安装
goto setname
)

安装

创建一个install.bat文件,具体内容如下:

@echo off
CHCP 65001
::添加跳转标签
:path
set /p startup=请输入服务目标程序路径:
if not exist %startup% (
echo %startup%路径不存在,请重新输入
goto :path
)
::通过跳转传递路径参数
call :filename %startup%
::判定执行是否合理
if  %errorlevel%==1 (
exit /b
)
:filename
::默认服务名
set file_name=%~n1
::echo %file_name%
:setname
::配置服务名称
set /p servicename=请输入服务名称(默认%file_name%):
::配置服务显示名称
if "%servicename%"=="" (
set servicename=%file_name%
)
::判定服务名称是否已存在
call isexist.bat %servicename%
if %errorlevel%==1060 (
goto setname
)
::配置服务描述
set /p discription=请输入服务描述(默认%file_name%):
if "%discription%"=="" (
set discription=%file_name%
)
::配置服务启动模式  
set mode=demand
::配置服务启动模式  
set /p servicemode=请输入服务启动模式(默认%mode%手动):
if "%servicemode%"=="" (
set servicemode=%mode%
)
::安装服务
sc create %servicename% binPath= %startup% start= %servicemode% DisplayName= %servicename%
::修改描述
sc description %servicename% %discription%
exit /b 1

需要注意的是,if条件语句执行体如果包含多条执行语句时,需要用使用()进行包裹,同时,与条件语句之间需要用空格进行分隔,同时必须是同行中添加(,否则将出现异常The syntax of the command is incorrect.这个常规异常

启动

@echo off
::CHCP 65001
set option="启动"
:::setname
::::输入服务名称
::set /p servicename=请输入需要%option%的服务名称:
::::判定服务名称是否为空
::if "%servicename%"=="" (
::echo 服务名称不能为空
::goto setname
::)
call input.bat %option%
sc start %servicename%
exit /b 0

停止

@echo off
::CHCP 65001
set option="停止"
call input.bat %option%
sc stop %servicename%
exit /b 0

卸载

@echo off
::CHCP 65001
set option="卸载"
call input.bat %option%
::执行服务删除操作
sc delete %servicename%
exit /b 0

组合

@echo off
CHCP 65001
::获取参数
set cmd=%1
::判定指令
if "%cmd%"=="" (
echo 输入%cmd%无效
goto help
)
::安装服务
if "%cmd%"=="install" (
call install.bat
goto finish
)
::卸载服务
if "%cmd%"=="uninstall" (
call uninstall.bat
goto finish
)
::启动服务
if "%cmd%"=="start" (
call start.bat
goto finish
)
::停止服务
if "%cmd%"=="stop" (
call stop.bat
goto finish
)
else (
::帮助指令
echo 输入%cmd%无效
:help
echo 输入help查看对应指令
echo scutil [command]
echo [command]如下:
echo install  安装服务
echo uninstall  卸载服务
echo start    启动服务
echo stop   停止服务
)
::退出执行
:finish
exit /b 0

测试运行

管理员启动cmd,切换目录到scutil.bat对应的目录,执行安装指令,当前服务测试路径为E:\Study\Servers\sctest\sctest.exesctest.exe为上一个章节的服务程序,完全符合windows服务化要求

>scutil install
Active code page: 65001
请输入服务目标程序路径:"E:\Study\Servers\sctest\sctest.exe"
请输入服务名称(默认sctest):
请输入服务描述(默认sctest):
请输入服务启动模式(默认demand手动):
[SC] CreateService SUCCESS
[SC] ChangeServiceConfig2 SUCCESS

查看本地服务sc query sctest

>sc query sctest
SERVICE_NAME: sctest
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 1077  (0x435)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

运行程序

>scutil start
Active code page: 65001
请输入需要启动的服务名称:sctest
SERVICE_NAME: sctest
        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                : 14244
        FLAGS              :

对应目录下,生成一个当前日期的内容输出文件,内容为不断追加的时间值

当前时间:Service Start
当前时间:22:03:56
当前时间:22:03:57
当前时间:22:03:58
当前时间:22:03:59
当前时间:22:04:00
当前时间:22:04:01
当前时间:22:04:02
当前时间:22:04:03
当前时间:22:04:04
当前时间:22:04:05

停止程序

>scutil stop
Active code page: 65001
请输入需要停止的服务名称:sctest
SERVICE_NAME: sctest
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
>sc query sctest
SERVICE_NAME: sctest
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

卸载程序

>scutil uninstall
Active code page: 65001
请输入需要卸载的服务名称:sctest
[SC] DeleteService SUCCESS
>sc query sctest
[SC] EnumQueryServicesStatus:OpenService FAILED 1060:
The specified service does not exist as an installed service

以上就是本章对于将sc.exe实现脚本化,进而实现程序服务化的交互式操作

总结

这些脚本虽然看似鸡肋,只是将指令进行了二次封装,实际上,这是笔者第一个比较系统化的对脚本的实践和应用,能够将这些指令以类似简单编程的方式进行处理也是一种经验的积累,后续将继续讲解笔者接触到的Windows服务化的其他工具的使用和思考

  • instsrvsrvany
  • Winsw
  • Nssm

获取上述内容中的服务测试源码项目,可关注私信或直接评论回复【sc.bat


相关文章
|
2月前
|
监控 关系型数据库 MySQL
PowerShell 脚本编写 :自动化Windows 开发工作流程
PowerShell 脚本编写 :自动化Windows 开发工作流程
77 0
|
3月前
|
Python Windows
python之windows脚本启动bat
python之windows脚本启动bat
|
4月前
|
安全 Shell Windows
记windows自定义bat脚本自启动
【8月更文挑战第27天】在Windows系统中,可让自定义bat脚本自启动的方法有两种:一是利用“启动”文件夹,通过创建bat脚本的快捷方式并将其放置于该文件夹;二是使用任务计划程序,创建一个启动时触发的任务来运行bat脚本。需确保脚本正确安全,避免对系统产生不良影响。
272 0
|
6月前
|
关系型数据库 MySQL 数据安全/隐私保护
windows系统bat批处理 mysql 脚本启动关闭
windows系统bat批处理 mysql 脚本启动关闭
226 3
|
6月前
|
Windows
windows系统vbs脚本 恶搞关不掉的窗口 以及解决办法
windows系统vbs脚本 恶搞关不掉的窗口 以及解决办法
136 2
|
6月前
|
Windows
windows系统vbs脚本 恶搞将系统搞崩 死机 以及解决
windows系统vbs脚本 恶搞将系统搞崩 死机 以及解决
62 1
|
6月前
|
Windows
windows系统vbs脚本 提取文件夹中的所有文件名
windows系统vbs脚本 提取文件夹中的所有文件名
47 0
|
6月前
|
应用服务中间件 nginx Windows
windows系统bat批处理 管理nginx启动 nginx脚本管理bat脚本管理生命周期windows一键nginx启动
windows系统bat批处理 管理nginx启动 nginx脚本管理bat脚本管理生命周期windows一键nginx启动
137 0
|
6月前
|
Java Windows
windows bat脚本实现快速配置JDK 环境变量
windows bat脚本实现快速配置JDK 环境变量
289 0
|
6月前
|
Linux 网络安全 Windows
ssh连接缓慢 ssh连接失败问题 Linux 脚本解决ssh连接缓慢问题,windows解决本地ssh连接失败
ssh连接缓慢 ssh连接失败问题 Linux 脚本解决ssh连接缓慢问题,windows解决本地ssh连接失败
72 0