测试TASKKILL的错误级别的语法

时间:2018-07-11 22:48:59

标签: batch-file

在下面显示的批处理文件的上下文中测试errorlevel的{​​{1}}的正确语法是什么?

TASKKILL

我正试图让我的批处理文件运行:Launch start "CloseMe" "C:\Program Files\internet explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User\1173051_SM_STP\Files\Stony Mountain Institute Lift Station.html" TIMEOUT 1 & :ShiftFocus wscript "C:\ProgramData\Schneider Electric\Citect SCADA 2016\User\1173051_SM_STP\Files\SendAltTab.vbs" TASKKILL /IM iexplore.exe /FI "WINDOWTITLE eq CloseMe - Internet Explorer" if %errorlevel% == 1 GOTO ShiftFocus :End exit ,然后测试结果。

如果结果为“ INFO:没有任务以指定条件运行”。我需要批处理文件才能再次尝试TASKKILL

如果结果为“成功:已将终止信号发送给...”。我需要关闭批处理文件。

要实现此目的,我使用了我所了解的herehere的if语句,标签和gotos。

我怀疑我错误地使用了错误级别,因为无论TASKKILL的错误级别如何,从批处理文件的角度来看,它的错误级别都是0。类似帖子的某些答案正在使用TASKKILL,而其他答案是使用%errorlevel%。无论我在批处理文件中使用哪种格式,无论errorlevel的实际结果如何,其错误级别均为0。

4 个答案:

答案 0 :(得分:2)

打开命令提示符窗口,然后运行if /?。输出帮助说明了如何使用自MS-DOS以来以及在命令块中都可以使用的语法if errorlevel X ...使用命令 IF 来纠正错误级别的检查。

if %errorlevel% == 1 goto ShiftFocus在以(开头和以匹配)结尾的命令块中不起作用,因为批处理文件编写的初学者期望由于Windows命令处理器替换了所有{{1 }}在整个命令块中按引用的环境变量的值执行,然后再执行该命令块。在命令提示符窗口中运行没有%variable%的批处理文件时,可以看到这种情况。

另请参见single line with multiple commands using Windows batch file,说明如何使用@echo off或使用运算符if errorlevel X ...&&来评估命令或应用程序的退出代码。

也可以使用||,这意味着退出代码等于或大于 if errorlevel 1 if not errorlevel 2 goto ShiftFocus等于或大于等于 {{1 }},例如像C,C ++,C#,JavaScript等中的1,在对退出代码2进行显式测试的情况下,需要排除退出代码if ((errorlevel >= 1) && (errorlevel < 2))

在带有{{1}的命令提示符窗口中运行1时,也可以启用delayed expansion并按照命令 SET 的说明使用它}。但是,我不建议仅使用延迟扩展来引起其他麻烦,并且由于对每个命令行进行两次解析而使批处理文件的处理速度变慢,因此我不建议仅将其用于评估命令或应用程序的退出代码。

但是,真正的问题是,在Internet Explorer上未运行批处理文件的情况下,应根据有问题的解释跳到标签128上,只需使用set /?就可以实现。

因此整个批处理文件可能是:

if !errorlevel! == 1 goto ShiftFocus

最好使用具有完整路径和文件扩展名的控制台应用程序(外部命令)来使批处理文件独立于环境变量ShiftFocusif errorlevel 128 goto ShiftFocus

不应该在没有选项:Launch start "CloseMe" "C:\Program Files\Internet Explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User\1173051_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\User\1173051_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,因为这会使测试批处理文件非常困难,无法从命令提示符窗口中运行而不是双击它。有关详细信息,请参见debugging a batch file

在跳转到PATHEXT并再次运行脚本之前,还需要等待一秒钟,因为快速循环运行脚本和exit对我来说没有意义。

但是由于aschipfl解释的原因,该批处理文件无法工作: TASKKILL 在使用过滤器选项{{1时,不会以CatCat写入的值128退出。 }},并且没有与过滤器匹配的正在运行的进程。

aschipfl发布了一种独立于语言的解决方案来解决 TASKKILL 的怪癖。

取决于语言的解决方案将使用此批处理文件:

/B

TASKKILL 命令行由 FOR 在后台以ShiftFocus开始的单独命令过程中执行。 TASKKILL 在此后台命令过程中输出的用于处理 STDOUT 的行由 FOR 捕获。然后,使用冒号作为分隔符将捕获的行拆分为子字符串。直到第一个冒号的字符串都分配给循环变量taskkill。此字符串在此取决于语言/FI:Launch start "CloseMe" "C:\Program Files\Internet Explorer\iexplore.exe" "file://C:\ProgramData\Schneider Electric\Citect SCADA 2016\User\1173051_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\User\1173051_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 。如果为cmd /C,则找不到带有窗口标题为I的Internet Explorer实例,导致实例在1秒后跳转到INFO并运行一次VBScript和 TASKKILL 再次。

如果批处理文件应在任何具有Windows Vista或独立于Windows语言的Windows版本的Windows计算机上运行,​​则不应使用此Windows语言依赖解决方案。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

taskkill /f /im wscript.exe
echo %errorlevel%
pause

%errorlevel%

  

0成功

     

1表示拒绝访问

     

128没什么可杀死的

答案 3 :(得分:0)

在将输出通过管道传递到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