批处理启动/停止Windows服务(升级版)


  1 @echo off
  2 rem Run as administrator
  3 %1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
  4 rem Switch to the file current directory
  5 cd /d "%~dp0"
  6 
  7 rem 设置本地为延迟扩展
  8 setlocal enabledelayedexpansion 
  9 
 10 :flag_loop
 11 
 12 cls
 13 rem echo %0
 14 
 15 rem 如果要增加其他的服务,只需要增加服务名称(服务名称可以包含空格),按分号分隔(仅修改这一处地方就可以)
 16 set WS=MariaDB10.4;MariaDB10.5;MSSQLSERVER;aspnet_state;ZyrhDeviceService;
 17 
 18 
 19 rem 数组下标开始,这里特意设计为从1开始
 20 set WS_START=1
 21 rem 数组元素数量,自动增长
 22 set WS_COUNT=1
 23 
 24 :flag_split
 25 rem 分割字符串WS,按分号;分隔
 26 rem tokens=1*,tokens表示分段的方式,tokens=1*表示第一个分隔符;之前的作为一部分,剩下的(*表示)作为一部分。这两部分在循环体总可以用%%a表示第一部分,%%b表示第二部分
 27 rem delims=;表示以分号作为分隔符
 28 for /f "tokens=1* delims=;" %%a in ("%WS%") do (
 29     rem echo n:%%a
 30     rem 将分割出来的字符串赋值给数组元素
 31     set WS[%WS_COUNT%]="%%a"
 32     set /a WS_COUNT+=1
 33     rem 将截取剩下的部分赋给变量WS
 34     set WS=%%b
 35 )
 36 rem 如果还有剩余,则继续分割
 37 if defined WS goto :flag_split
 38 
 39 set /a WS_COUNT-=1
 40 
 41 echo.
 42 echo   [:Loop]  Please select service id:
 43 for /l %%n in (%WS_START%, 1, %WS_COUNT%) do ( 
 44    rem echo wn:!WS[%%n]! 
 45    rem 启用了变量延迟,变量需要用!!括起来
 46    call :flag_state !WS[%%n]! %%n
 47 )
 48 
 49 :flag_type
 50 echo.
 51 set /p "type=  [:Type]  Please input service id (%WS_START% - %WS_COUNT%) (R - :Loop, Q - Exit) : "
 52 
 53 set return=%type%
 54 call :upper_case %type% return
 55 set type=%return%
 56 set /a num=%type%*1
 57 
 58 call :check_exit %type%
 59 
 60 if %type%==%num% (
 61     if %num% gtr %WS_COUNT% (
 62         echo   Please enter the numbers %WS_START% - %WS_COUNT% .
 63         goto flag_type
 64     ) else if %num% leq 0 (
 65         echo   Please enter the numbers %WS_START% - %WS_COUNT% !
 66         goto flag_type
 67     ) else (
 68         call :flag_state !WS[%type%]! %type%
 69         call :flag_action !WS[%type%]! %type%
 70     )
 71 ) else if "%type%" == "R" (
 72     goto flag_loop
 73 ) else (
 74     goto flag_type
 75 )
 76 
 77 goto comments
 78     函数
 79     根据用户输入确定不同的操作
 80     参数1: 要操作的服务名称,字符串
 81 :comments
 82 :flag_action
 83     echo.
 84     rem 这里的□ (<0x08>)是一个退格符,是为了显示出后面的两个空格位置
 85     set /p "action=  Please input action key (S - Start, X - Stop, C - :Config, N - :Name, D - :Desc, R - :Type, Q - Exit) : "
 86 
 87     set return=%action%
 88     call :upper_case %action% return
 89     set action=%return%
 90 
 91     call :check_exit %action%
 92 
 93     if "%action%" == "S" (
 94         call :flag_start "%~1" %~2
 95     ) else if "%action%" == "X" (
 96         call :flag_stop "%~1" %~2
 97     ) else if "%action%" == "C" (
 98         call :flag_config "%~1"
 99     ) else if "%action%" == "N" (
100         call :flag_name "%~1"
101     ) else if "%action%" == "D" (
102         call :flag_desc "%~1"
103     ) else if "%action%" == "R" (
104         goto flag_type
105     ) else (
106         goto flag_action
107     )
108 goto:eof
109 
110 goto comments
111     函数
112     查询服务状态,并返回明确的服务状态,如 RUNNING 或 STOPPED,接受两个参数
113     参数1: 要查询的服务名称,字符串
114     参数2: 接受返回结果的变量
115 :comments
116 :flag_state
117     set st=
118     call :flag_qc "%~1" %~2 st
119 
120     set fn="%~1_tmp_123.log"
121     rem 查询服务状态信息,提取 STATE 内容并写入到文件中
122     sc query "%~1" |findstr "STATE" > %fn%
123 
124     set value=
125     rem 读取文件内容到value变量
126     set /p value=<./%fn%
127 
128     del %fn%
129 
130     set index=2
131     rem 按冒号:分割字符串,并提取第2部分的内容(下标是从1开始的)
132     for /F "tokens=%index% delims=:" %%a in ("%value%") do set value=%%a
133 
134     rem 按空格分割字符串,并提取第2部分的内容(下标是从1开始的)
135     for /F "tokens=%index% delims= " %%a in ("%value%") do set value=%%a
136     echo   %~2  %~1            ----  %value%    ----  %st%
137 goto:eof
138 
139 :flag_qc
140     set fn="%~1_qc_123.log"
141     rem 查询服务配置信息,提取 START_TYPE 内容并写入到文件中
142     sc qc "%~1" |findstr "START_TYPE" > %fn%
143 
144     set value=
145     rem 读取文件内容到value变量
146     set /p value=<./%fn%
147 
148     del %fn%
149 
150     set index=2
151     rem 按冒号:分割字符串,并提取第2部分的内容(下标是从1开始的)
152     for /F "tokens=%index% delims=:" %%a in ("%value%") do set value=%%a
153 
154     rem 截取字符串,从第5个字符开始(空格也算是字符)
155     set value=%value:~5%
156 
157     rem 替换双空格为单个空格
158     set value=%value:  = %
159 
160     rem echo   %~2     %~1         --------  %value%
161 
162     rem 将返回值赋值给变量3
163     set %~3=%value%
164 goto:eof
165 
166 :flag_start
167     echo   start %~1
168     sc start "%~1"
169     timeout 2
170     call :flag_state "%~1" %~2
171     goto flag_type
172 goto:eof
173 
174 :flag_stop
175     echo   stop %~1
176     sc stop "%~1"
177     timeout 2
178     call :flag_state "%~1" %~2
179     goto flag_type
180 goto:eof
181 
182 :flag_config
183     echo.
184     set /p "config=  Please input config key (1 - Automatic, 2 - Manual, 3 - Disabled, 4 - Delayed Auto, R - :Type, Q - Exit) : "
185 
186     call :check_exit %config%
187 
188     rem 设置服务启动方式 auto - Automatic, demand - Manual, disabled - Disabled, delayed-auto - Automatic (Delayed Start)
189     if "%config%" == "1" (
190         rem start= 这里需要一个空格
191         sc config "%~1" start= auto
192     ) else if "%config%" == "2" (
193         sc config "%~1" start= demand
194     ) else if "%config%" == "3" (
195         sc config "%~1" start= disabled
196     ) else if "%config%" == "4" (
197         sc config "%~1" start= delayed-auto
198     ) else if "%config%" == "R" (
199         goto flag_type
200     ) else (
201         goto flag_config
202     )
203 goto:eof
204 
205 :flag_name
206     echo.
207     set /p "name=  Please input service name (R - :Type, Q - Exit) : "
208 
209     call :check_exit %name%
210 
211     if "%name%" == "R" (
212         goto flag_type
213     ) else (
214         sc config "%~1" DisplayName= "%name%"
215         goto flag_type
216     )
217 goto:eof
218 
219 :flag_desc
220     echo.
221     set /p "desc=  Please input service description (R - :Type, Q - Exit) : "
222 
223     call :check_exit %desc%
224 
225     if "%desc%" == "R" (
226         goto flag_type
227     ) else (
228         sc description "%~1" "%desc%"
229         goto flag_type
230     )
231 goto:eof
232 
233 :check_exit
234     if "%~1" == "Q" (
235         goto flag_exit
236     ) else if "%~1" == "EXIT" (
237         goto flag_exit
238     ) else if "%~1" == "QUIT" (
239         goto flag_exit
240     )
241 goto:eof
242 
243 :upper_case
244     set val=%~1
245     for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do call set val=%%val:%%i=%%i%%
246     set %~2=%val%
247 goto:eof
248 
249 :lower_case
250     set val=%~1
251     for %%i in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do call set val=%%val:%%i=%%i%%
252     set %~2=%val%
253 goto:eof
254 
255 :flag_exit
256 exit