Выходить из списка задач в командном файле? - PullRequest
4 голосов
/ 11 февраля 2011

Я выполняю следующую команду в метке внутри командного файла: tasklist.exe / FI "USERNAME eq% USERDOMAIN% \% USERNAME%" / FI "IMAGENAME eq% 1" / FI "PID eq% 2" 2> nul && echo errorl:% уровень ошибки%

% 1 - процесс запущен, а% 2 - его PID. Даже если процесс и его PID совпадают или не совпадают, я получаю «errorl: 1» в o / p.

Я не уверен, что здесь не так. Есть идеи?

Ответы [ 4 ]

9 голосов
/ 07 марта 2012

Вы можете передать список задач через команду 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
6 голосов
/ 11 февраля 2011

На мой взгляд, вы вообще не можете использовать уровень ошибки,
потому что tasklist всегда возвращает 0, даже если pid не найден.

Полагаю, вам нужно проанализировать вывод списка задач.

@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 голосов
/ 11 февраля 2011

% переменных% раскрываются перед выполнением строки, поэтому% 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
0 голосов
/ 22 августа 2016

Простое решение этой проблемы, учитывая, что

 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!
...