6

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

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”。

我不确定这里有什么问题。任何的想法?

4

5 回答 5

9

您可以通过 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
于 2012-03-06T21:27:26.990 回答
7

在我看来,你根本不能使用 errorlevel,
因为即使找不到 pid , tasklist也总是返回 0。

我想,你必须解析任务列表的输出。
获取命令的输出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
)
于 2011-02-11T13:48:14.627 回答
2

%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
于 2011-02-11T13:41:22.440 回答
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!
于 2016-08-22T07:59:59.333 回答
0

tasklist成功执行时返回 0:
如果您正在寻找某个进程或某个进程的某个属性的存在,一种方法是提供属性tasklist并检查它是否返回任何进程名称。如果没有找到匹配的进程,它将返回“INFO:没有匹配指定条件的任务正在运行”。

tasklist可以通过for命令嵌入(并解析命令输出)或通过接受正则表达式和通配符的 or 过滤findfindstr检查结果。

例如。要检查任何进程是否正在使用以下标准运行:

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 上测试

不请自来的广告弹出

于 2021-05-14T11:03:41.777 回答