问题
I am executing following command in a label inside a batch file: tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %1" /FI "PID eq %2" 2>nul && echo errorl:%errorlevel%
%1 is process running and %2 is its PID. Even if process and its PID matches or doesnt matches, I m getting "errorl:1" in o/p.
I am not sure whats wrong here. Any idea?
回答1:
In my opinion, you can't use errorlevel at all,
because tasklist always returns a 0 even if the pid isn't found.
I suppose, you have to parse the output of tasklist.
@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
)
回答2:
You could pipe tasklist through the find command and get an errorlevel off of it.
Example:
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
回答3:
%variables% are expanded before executing the line, so %errorlevel% will expand to some old value. (The fact that the code after && executes at all is your clue that the command returned 0)
You options are:
- Use
%errorlevel%
or the more correctIF errorlevel 1 ...
on the next line - Call
setlocal ENABLEDELAYEDEXPANSION
first and then use!errorlevel!
Edit: I guess tasklist is buggy and/or stupid when it comes to exit codes, I wrote some code that does not use the exit code at all:
@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)
Run it as test.cmd SOTEST and it prints:
calc.exe:4852 is running
dummy.exe:666 is NOT running
回答4:
Easy solution to this, given that
1) you can't get an errorlevel from tasklist, and
2) you can't directly pipe it to a FIND
Just write it to a file using output redirection and use FIND to check the file. Each time this is run, it will overwrite the previous iteration, so no need to even do any file cleanup. Amazing how many bat/cmd file limitations can be overcome with a simple scratchpad file!!
: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!
来源:https://stackoverflow.com/questions/4969595/exit-status-of-tasklist-in-batch-file