File 批处理文件中任务列表的退出状态?

File 批处理文件中任务列表的退出状态?,file,batch-file,exit,status,tasklist,File,Batch File,Exit,Status,Tasklist,我正在批处理文件内的标签中执行以下命令: 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中也会得到“error:1” 我不确定这里出了什么问题。有什么想法吗?%variables%在执行该行

我正在批处理文件内的标签中执行以下命令:

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中也会得到“error:1”


我不确定这里出了什么问题。有什么想法吗?

%variables%在执行该行之前已展开,因此%errorlevel%将展开为某个旧值。(事实上,&&之后执行的代码就是命令返回0的线索)

你的选择是:

  • 在下一行使用
    %errorlevel%
    或更正确的
    如果errorlevel 1…
  • 首先调用
    setlocal ENABLEDELAYEDEXPANSION
    ,然后使用
    !错误等级
编辑: 我猜tasklist在退出代码方面有缺陷和/或愚蠢,我写了一些根本不使用退出代码的代码:

@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

在我看来,您根本不能使用errorlevel,
因为即使找不到pid,任务列表始终返回0

我想,您必须解析tasklist的输出。
要获取命令的输出,
FOR/F
是一个不错的选择

为了避免在
中引用/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
)

您可以通过find命令传递任务列表,并从中获取errorlevel

例如:

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

简单解决方案

 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
的结果可以通过
进行检查,以进行
命令嵌入(和解析命令输出),或者通过
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上测试


但是:如果errorlevel 1为真,如果errorlevel为1或更大,这可能是意外行为,我更喜欢%errorlevel%EQU 1或%errorlevel%GTR 1Hi Anders,我已经在批处理脚本中使用setlocal ENABLEDELAYEDEXPANSION,并以您描述的相同方式访问参数。但它不起作用。@user613114:仅仅设置ENABLEDELAYEDEXPANSION是不够的,您正在使用吗!错误等级!而不是%errorlevel%?甚至!错误等级!不起作用,因为errorlevel只得到1,如果参数格式错误Hello Jeb,您的修改工作得很好:D非常感谢。此代码比我的代码短一些,但我更喜欢在禁用enableDelayedExpansion的情况下运行,以减少字符串扩展问题,另外,FINDSTR是XP+@jeb。最好解释一下为什么这里使用FOR循环,然后再解释一下延迟扩展在这个上下文中的作用。例如,
对于/F“delims=*”%%P IN('tasklist.exe/NH/FI“USERNAME eq%USERDOMAIN%\%USERNAME%”“/FI“IMAGENAME eq%1”/FI“PID eq%2”),ECHO发现%%P
会产生完全相同的输出吗?@Jimadine感谢您的提示。我编辑了答案。对于你的问题:我想你需要
。|findstr“%2”
以确保只查找匹配项,而不是像
这样的消息没有这样的过程。但目前我无法重新测试,因为我大部分时间都在Ubuntu上@jeb感谢您添加了解释。您是对的,
findstr
过滤掉任务列表的
信息:没有运行符合指定条件的任务。
messages在windows 10中使用任务列表时,似乎没有修改错误级别。