我正在批处理文件中的标签中执行以下命令:
tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %1" /FI "PID eq %2" 2>nul && echo errorl:%errorlevel%
%1 是正在运行的进程,%2 是它的 PID。 即使进程及其 PID 匹配或不匹配,我也会在 o/p 中收到“errorl:1”
我不确定这里出了什么问题。有什么想法吗?
您可以通过 find 命令通过管道传输任务列表并从中获取错误级别。
例子:
tasklist | find "firefox.exe"
echo Error level = %ERRORLEVEL%
REM If firefox is running, the errorlevel is set to 0
REM If firefox is not running, errorlevel is set to 1
在我看来,你根本不能使用errorlevel,
因为 tasklist 总是返回 0,即使找不到 pid。
我想,你必须解析任务列表的输出。
要获取命令的输出,
FOR /F
是一个不错的选择。
为了避免
FOR /F
中的引用问题,我首先构建一个 cmd
变量,该变量通过延迟扩展来扩展以避免特殊字符的任何副作用。
@echo off
setlocal enableDelayedExpansion
set "cmd=tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %1" /FI "PID eq %2""
for /F "delims=*" %%p in ('!cmd! ^| findstr "%2" ') do (
echo found %%p
)
%variables% 在执行该行之前扩展,因此 %errorlevel% 将扩展为某个旧值。 (&& 之后的代码完全执行的事实是命令返回 0 的线索)
您的选择是:
%errorlevel%
或更正确的IF errorlevel 1 ...
setlocal ENABLEDELAYEDEXPANSION
然后使用!errorlevel!
编辑: 我猜任务列表在退出代码方面有问题和/或愚蠢,我写了一些根本不使用退出代码的代码:
@echo off
if "%~1"=="SOTEST" (
start calc
ping -n 2 localhost >nul
for /F "tokens=1,2 skip=3" %%A in ('tasklist /FI "IMAGENAME eq calc.exe"') do (
call "%~0" %%A %%B
)
call "%~0" dummy.exe 666
goto :EOF
)
goto main
:IsTaskRunning
setlocal ENABLEEXTENSIONS&set _r=0
>nul 2>&1 (for /F "tokens=1,2" %%A in ('tasklist /FO LIST %*') do (
if /I "%%~A"=="PID:" set _r=1
))
endlocal&set IsTaskRunning=%_r%&goto :EOF
:main
call :IsTaskRunning /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %1" /FI "PID eq %2"
if %IsTaskRunning% gtr 0 (echo.%1:%2 is running) else (echo.%1:%2 is NOT running)
将其作为 test.cmd SOTEST 运行并打印:
calc.exe:4852 is running
dummy.exe:666 is NOT running
Easy 解决方案,鉴于此
1) you can't get an errorlevel from tasklist, and
2) you can't directly pipe it to a FIND
只需使用输出重定向将其写入文件并使用 FIND 来检查文件。每次运行时,它都会覆盖之前的迭代,因此甚至不需要进行任何文件清理。一个简单的暂存器文件可以克服多少 bat/cmd 文件限制,这真是太神奇了!!
:TOP
rem swap rems from good to bad to test
set findvar=goodfile.exe
rem set findvar=badfile.exe
set scratchfile=scratch.txt
tasklist /fi "status eq running" /fi "imagename eq %findvar%">%scratchfile%
type %scratchfile%
pause
echo Looking for %findvar%
find "%findvar%" %scratchfile%
echo Error level = %errorlevel%
pause
IF errorlevel 1 GOTO BAD
IF errorlevel 0 GOTO GOOD
GOTO OTHER
:BAD
echo Errrlevel 1 - task not found
PAUSE
GOTO TOP
:GOOD
echo Errrlevel 0 - task is running
pause
GOTO TOP
:OTHER
echo something else ????? you blew it somewhere!
tasklist
执行成功返回0:tasklist
并检查它是否返回任何进程名称。如果找不到匹配的进程,它将返回“信息:没有运行符合指定条件的任务。”
tasklist
的结果可以通过 for
命令嵌入(和解析命令输出)或通过 find
或 findstr
过滤来检查,它接受正则表达式和通配符。
例如。检查是否有任何进程正在运行以下标准:
tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %1" /FI "PID eq %2" | find /v "No task" >nul && (echo process exists) || (echo na man).
除了底层进程,如“firefox.exe”之外,上述方法还可以查找是否有文件(窗口)打开。
例如。关闭高速 vpn 广告窗口,如果/当它在没有通知的情况下弹出时:
tasklist /fi "windowtitle eq High-Speed*" | find /v "No task" >nul && (taskkill /fi "windowtitle eq High-Speed*")
在 Win 10 CMD 上测试