测试 TASKKILL 错误级别的语法
syntax for testing TASKKILL's errorlevel
在下面显示的批处理文件的上下文中测试 TASKKILL
的 errorlevel
的正确语法是什么?
:Launch
start "CloseMe" "C:\Program Files\internet explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\Stony Mountain Institute Lift Station.html"
TIMEOUT 1 &
:ShiftFocus
wscript "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\SendAltTab.vbs"
TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer"
if %errorlevel% == 1 GOTO ShiftFocus
:End
exit
我正在尝试将我的批处理文件 运行 TASKKILL
然后测试结果。
如果结果是 "INFO: No tasks running with the specified criteria." 我需要批处理文件再试一次 TASKKILL
。
如果结果是"SUCCESS: Sent termination signal to ... ."我需要关闭批处理文件。
为了实现这一点,我使用了我在 here and here 中学到的 if 语句、标签和 goto。
我怀疑我错误地使用了错误级别,因为无论 TASKKILL
做什么,从我的批处理文件的角度来看,它的错误级别都是 0。类似帖子的一些答案使用 %errorlevel%
和其他人正在使用 errorlevel
。无论我在我的批处理文件中使用哪个,它都会看到 0 的错误级别,而不管 TASKKILL
.
的实际结果如何
taskkill /f /im wscript.exe
echo %errorlevel%
pause
%errorlevel%
是
0 for success
1 for Access Denied
128 for nothing to kill
打开命令提示符 window 和 运行 if /?
。输出帮助解释了如何使用自 MS-DOS 以来工作的语法 if errorlevel X ...
以及在命令块中工作的语法 IF 来更正检查错误级别。
if %errorlevel% == 1 goto ShiftFocus
在以 (
开始并以匹配 )
结束的命令块中不起作用,因为 Windows 命令处理器替换了批处理文件编写的初学者在执行命令块之前,根据引用环境变量的值,整个命令块中出现的所有 %variable%
。这可以在命令提示符 window.
中 运行 在没有 @echo off
的批处理文件中看到
另请参阅 single line with multiple commands using Windows batch file 解释如何使用 if errorlevel X ...
或使用运算符 &&
和 ||
.[=51= 评估命令或应用程序的退出代码]
也可以使用 if errorlevel 1 if not errorlevel 2 goto ShiftFocus
,这意味着退出代码 大于或等于 1
但 不大于或等于 2
,即像 C、C++、C# 中的 if ((errorlevel >= 1) && (errorlevel < 2))
、JavaScript 等,如果需要对退出代码 1
进行显式测试排除退出代码 128
.
也可以启用 delayed expansion 并按照 运行ning set /?
上命令 SET 输出的帮助说明使用它在命令提示符 window 和 if !errorlevel! == 1 goto ShiftFocus
中。但是,延迟扩展的使用可能会导致其他问题,并且由于对每个命令行进行双重解析而使批处理文件处理速度变慢,我真的不建议将其仅用于评估命令或应用程序的退出代码。
然而,真正的问题是在没有 运行 的 Internet Explorer 上,批处理文件应该跳转到标签 ShiftFocus
根据有问题的解释,这可以通过使用 if errorlevel 128 goto ShiftFocus
.
所以整个批处理文件可以是:
:Launch
start "CloseMe" "C:\Program Files\Internet Explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\Stony Mountain Institute Lift Station.html"
%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul
:ShiftFocus
%SystemRoot%\System32\wscript.exe "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\SendAltTab.vbs"
%SystemRoot%\System32\taskkill.exe /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer"
if errorlevel 128 %SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul & goto ShiftFocus
exit /B
最好使用具有完整路径和文件扩展名的控制台应用程序(外部命令),使批处理文件独立于环境变量 PATH
和 PATHEXT
。
并且命令 exit
不应该在没有选项 /B
的情况下使用,因为它使得在命令提示符 window 中 运行 测试批处理文件变得非常困难而不是双击它。详情见 debugging a batch file。
在跳转到 ShiftFocus
和 运行 脚本之前添加了额外的一秒钟等待,因为快速 运行 脚本和 taskkill
循环对我来说没有意义。
但是由于 aschipfl: TASKKILL does not exit with value 128 as written by CatCat 在使用过滤器选项 /FI
中解释的原因,此批处理文件不起作用,并且没有 运行ning 进程匹配过滤器。
发布了解决 TASKKILL 这个问题的独立于语言的解决方案
依赖于语言的解决方案将使用此批处理文件:
:Launch
start "CloseMe" "C:\Program Files\Internet Explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\Stony Mountain Institute Lift Station.html"
%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul
:ShiftFocus
%SystemRoot%\System32\wscript.exe "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\SendAltTab.vbs"
for /F "delims=:" %%I in ('%SystemRoot%\System32\taskkill.exe /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer"') do if "%%I" == "INFO" %SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul & goto ShiftFocus
exit /B
TASKKILL 命令行由 FOR 在后台以 cmd /C
启动的单独命令进程中执行。 TASKKILL 输出的用于处理此后台命令进程中的 STDOUT 的行被 FOR 捕获。然后使用冒号作为分隔符将捕获的行拆分为子字符串。第一个冒号之前的字符串被分配给循环变量I
。此字符串在这里依赖于语言 INFO
或 SUCCESS
。在 INFO
的情况下,没有找到带有 window 标题 CloseMe - Internet Explorer
的 Internet Explorer 实例,导致在 1 秒后跳转到 ShiftFocus
并且 运行 将 VBScript 和TASKKILL 再一次。
如果批处理文件应该 运行 在装有 Windows Vista 或更高版本 Windows 的任何 Windows 机器上,则不应使用此 Windows 语言相关解决方案] 版本独立于 Windows.
的语言
taskkill
清除 ErrorLevel
当你提供了一个过滤器 /FI
导致不匹配!但是,当您仅过滤图像名称 (/IM
) 或进程 ID (/PID
) 时,如果未遇到任何匹配项,ErrorLevel
将设置为 128
。
因此,我将通过 tasklist
预过滤进程,并使用 taskkill
及其 /PID
过滤器:
:LOOP
rem // Establish a short wait time to not heavily load the processor:
> nul timeout /T 1 /NOBREAK
rem // Prefilter processes and retrieve the PID of the applicable one:
set "PID=" & for /F "tokens=1* delims=:" %%T in ('
tasklist /FI "IMAGENAME eq iexplore.exe" /FI "WINDOWTITLE eq CloseMe - Internet Explorer" /FO LIST
') do if "%%T"=="PID" for /F %%W in ("%%U") do set "PID=%%W"
rem // Loop back in case no PID could be retrieved:
if not defined PID goto :LOOP
rem // Try to kill the task and loop back in case of failure:
taskkill /PID %PID% || goto :LOOP
当您将输出通过管道传输到 find
命令时,您可以保留过滤器,因此您评估 find
的错误级别而不是 taskkill
的错误级别:
:ShiftFocus
...
TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer" | find "SUCCESS:" && goto :eof
goto :ShiftFocus
或
:ShiftFocus
...
TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer" | find "No tasks running" && goto :ShiftFocus
在下面显示的批处理文件的上下文中测试 TASKKILL
的 errorlevel
的正确语法是什么?
:Launch
start "CloseMe" "C:\Program Files\internet explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\Stony Mountain Institute Lift Station.html"
TIMEOUT 1 &
:ShiftFocus
wscript "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\SendAltTab.vbs"
TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer"
if %errorlevel% == 1 GOTO ShiftFocus
:End
exit
我正在尝试将我的批处理文件 运行 TASKKILL
然后测试结果。
如果结果是 "INFO: No tasks running with the specified criteria." 我需要批处理文件再试一次 TASKKILL
。
如果结果是"SUCCESS: Sent termination signal to ... ."我需要关闭批处理文件。
为了实现这一点,我使用了我在 here and here 中学到的 if 语句、标签和 goto。
我怀疑我错误地使用了错误级别,因为无论 TASKKILL
做什么,从我的批处理文件的角度来看,它的错误级别都是 0。类似帖子的一些答案使用 %errorlevel%
和其他人正在使用 errorlevel
。无论我在我的批处理文件中使用哪个,它都会看到 0 的错误级别,而不管 TASKKILL
.
taskkill /f /im wscript.exe
echo %errorlevel%
pause
%errorlevel%
是
0 for success
1 for Access Denied
128 for nothing to kill
打开命令提示符 window 和 运行 if /?
。输出帮助解释了如何使用自 MS-DOS 以来工作的语法 if errorlevel X ...
以及在命令块中工作的语法 IF 来更正检查错误级别。
if %errorlevel% == 1 goto ShiftFocus
在以 (
开始并以匹配 )
结束的命令块中不起作用,因为 Windows 命令处理器替换了批处理文件编写的初学者在执行命令块之前,根据引用环境变量的值,整个命令块中出现的所有 %variable%
。这可以在命令提示符 window.
@echo off
的批处理文件中看到
另请参阅 single line with multiple commands using Windows batch file 解释如何使用 if errorlevel X ...
或使用运算符 &&
和 ||
.[=51= 评估命令或应用程序的退出代码]
也可以使用 if errorlevel 1 if not errorlevel 2 goto ShiftFocus
,这意味着退出代码 大于或等于 1
但 不大于或等于 2
,即像 C、C++、C# 中的 if ((errorlevel >= 1) && (errorlevel < 2))
、JavaScript 等,如果需要对退出代码 1
进行显式测试排除退出代码 128
.
也可以启用 delayed expansion 并按照 运行ning set /?
上命令 SET 输出的帮助说明使用它在命令提示符 window 和 if !errorlevel! == 1 goto ShiftFocus
中。但是,延迟扩展的使用可能会导致其他问题,并且由于对每个命令行进行双重解析而使批处理文件处理速度变慢,我真的不建议将其仅用于评估命令或应用程序的退出代码。
然而,真正的问题是在没有 运行 的 Internet Explorer 上,批处理文件应该跳转到标签 ShiftFocus
根据有问题的解释,这可以通过使用 if errorlevel 128 goto ShiftFocus
.
所以整个批处理文件可以是:
:Launch
start "CloseMe" "C:\Program Files\Internet Explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\Stony Mountain Institute Lift Station.html"
%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul
:ShiftFocus
%SystemRoot%\System32\wscript.exe "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\SendAltTab.vbs"
%SystemRoot%\System32\taskkill.exe /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer"
if errorlevel 128 %SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul & goto ShiftFocus
exit /B
最好使用具有完整路径和文件扩展名的控制台应用程序(外部命令),使批处理文件独立于环境变量 PATH
和 PATHEXT
。
并且命令 exit
不应该在没有选项 /B
的情况下使用,因为它使得在命令提示符 window 中 运行 测试批处理文件变得非常困难而不是双击它。详情见 debugging a batch file。
在跳转到 ShiftFocus
和 运行 脚本之前添加了额外的一秒钟等待,因为快速 运行 脚本和 taskkill
循环对我来说没有意义。
但是由于 aschipfl: TASKKILL does not exit with value 128 as written by CatCat 在使用过滤器选项 /FI
中解释的原因,此批处理文件不起作用,并且没有 运行ning 进程匹配过滤器。
依赖于语言的解决方案将使用此批处理文件:
:Launch
start "CloseMe" "C:\Program Files\Internet Explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\Stony Mountain Institute Lift Station.html"
%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul
:ShiftFocus
%SystemRoot%\System32\wscript.exe "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User73051_SM_STP\Files\SendAltTab.vbs"
for /F "delims=:" %%I in ('%SystemRoot%\System32\taskkill.exe /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer"') do if "%%I" == "INFO" %SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul & goto ShiftFocus
exit /B
TASKKILL 命令行由 FOR 在后台以 cmd /C
启动的单独命令进程中执行。 TASKKILL 输出的用于处理此后台命令进程中的 STDOUT 的行被 FOR 捕获。然后使用冒号作为分隔符将捕获的行拆分为子字符串。第一个冒号之前的字符串被分配给循环变量I
。此字符串在这里依赖于语言 INFO
或 SUCCESS
。在 INFO
的情况下,没有找到带有 window 标题 CloseMe - Internet Explorer
的 Internet Explorer 实例,导致在 1 秒后跳转到 ShiftFocus
并且 运行 将 VBScript 和TASKKILL 再一次。
如果批处理文件应该 运行 在装有 Windows Vista 或更高版本 Windows 的任何 Windows 机器上,则不应使用此 Windows 语言相关解决方案] 版本独立于 Windows.
的语言taskkill
清除 ErrorLevel
当你提供了一个过滤器 /FI
导致不匹配!但是,当您仅过滤图像名称 (/IM
) 或进程 ID (/PID
) 时,如果未遇到任何匹配项,ErrorLevel
将设置为 128
。
因此,我将通过 tasklist
预过滤进程,并使用 taskkill
及其 /PID
过滤器:
:LOOP
rem // Establish a short wait time to not heavily load the processor:
> nul timeout /T 1 /NOBREAK
rem // Prefilter processes and retrieve the PID of the applicable one:
set "PID=" & for /F "tokens=1* delims=:" %%T in ('
tasklist /FI "IMAGENAME eq iexplore.exe" /FI "WINDOWTITLE eq CloseMe - Internet Explorer" /FO LIST
') do if "%%T"=="PID" for /F %%W in ("%%U") do set "PID=%%W"
rem // Loop back in case no PID could be retrieved:
if not defined PID goto :LOOP
rem // Try to kill the task and loop back in case of failure:
taskkill /PID %PID% || goto :LOOP
当您将输出通过管道传输到 find
命令时,您可以保留过滤器,因此您评估 find
的错误级别而不是 taskkill
的错误级别:
:ShiftFocus
...
TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer" | find "SUCCESS:" && goto :eof
goto :ShiftFocus
或
:ShiftFocus
...
TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer" | find "No tasks running" && goto :ShiftFocus