Как проверить, запущен ли процесс через пакетный пакет script

Как проверить, работает ли приложение из пакетного файла (cmd)?

Мне не нужно запускать другой экземпляр, если программа уже запущена. (Я не могу изменить приложение, чтобы сделать его единственным экземпляром.)

Также приложение может работать как любой пользователь.

Ответ 1

Еще одна возможность, с которой я столкнулся, с помощью grep:

tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Program is running

Не нужно сохранять дополнительный файл, поэтому я предпочитаю этот метод.

Ответ 2

Вот как я это разработал:

tasklist /FI "IMAGENAME eq notepad.exe" /FO CSV > search.log

FOR /F %%A IN (search.log) DO IF %%~zA EQU 0 GOTO end

start notepad.exe

:end

del search.log

Вышеуказанное откроет Notepad, если оно еще не запущено.

Изменить: обратите внимание, что это не будет искать приложения, скрытые из списка задач. Это будет включать любые запланированные задачи, выполняемые как разные пользователи, поскольку они автоматически скрыты.

Ответ 3

Мне нравится решение Chaosmaster! Но я искал решение, которое не запускает другую внешнюю программу (например, find.exe или findstr.exe). Поэтому я добавил идею из решения Matt Lacey, которая создает также предотвращаемый временный файл. В конце я мог найти довольно простое решение, поэтому я поделился им...

SETLOCAL EnableExtensions
set EXE=myprog.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto FOUND
echo Not running
goto FIN
:FOUND
echo Running
:FIN

Это работает для меня красиво...

Ответ 4

В Windows вы можете использовать инструментарий управления Windows (WMI), чтобы гарантировать, что приложения с указанной командной строкой не запущены, например:

wmic process where (name="nmake.exe") get commandline | findstr /i /c:"/f load.mak" /c:"/f build.mak" > NUL && (echo THE BUILD HAS BEEN STARTED ALREADY! > %ALREADY_STARTED% & exit /b 1)

Ответ 5

Предложение npocmaka использовать QPROCESS вместо TASKLIST велико, но его ответ настолько большой и сложный, что я чувствую себя обязанным опубликовать довольно упрощенную версию, которая, я думаю, решит проблему большинства неусовершенствованных пользователей:

QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"

Приведенный выше код был протестирован в Windows 7 с пользователем с настройками администратора.

Ответ 6

Я использую PV.exe из http://www.teamcti.com/pview/prcview.htm, установленный в Program Files\PV с таким пакетным файлом:

@echo off
PATH=%PATH%;%PROGRAMFILES%\PV;%PROGRAMFILES%\YourProgram
PV.EXE YourProgram.exe >nul
if ERRORLEVEL 1 goto Process_NotFound
:Process_Found
echo YourProgram is running
goto END
:Process_NotFound
echo YourProgram is not running
YourProgram.exe
goto END
:END

Ответ 7

Ответ TrueY казался самым изящным решением, однако мне пришлось немного поработать, потому что я не понимал, что именно происходит. Позвольте мне прояснить ситуацию, надеюсь, сэкономить некоторое время для следующего человека.

TrueY modified Отвечено:

::Change the name of notepad.exe to the process .exe that you're trying to track
::Process names are CASE SENSITIVE, so notepad.exe works but Notepad.exe does NOT
::Do not change IMAGENAME
::You can Copy and Paste this into an empty batch file and change the name of
::notepad.exe to the process you'd like to track
::Also, some large programs take a while to no longer show as not running, so
::give this batch a few seconds timer to avoid a false result!!

@echo off
SETLOCAL EnableExtensions

set EXE=notepad.exe

FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto ProcessFound

goto ProcessNotFound

:ProcessFound

echo %EXE% is running
goto END
:ProcessNotFound
echo %EXE% is not running
goto END
:END
echo Finished!

В любом случае, я надеюсь, что это поможет. Я знаю, что иногда чтение партии/командной строки иногда бывает путаным, если вы новичок, как я.

Ответ 8

Ответ предоставленный Мэттом Лэйси, работает для Windows XP. Однако в Windows Server 2003 строка

 tasklist /FI "IMAGENAME eq notepad.exe" /FO CSV > search.log

возвращает

INFO: не выполняются задачи, которые соответствуют указанным критериям.

который затем считывается при запуске процесса.

У меня нет кучи опыта работы с пакетными сценариями, поэтому моя мысль заключается в том, чтобы затем искать имя процесса в файле search.log и передавать результаты в другой файл и искать для любого вывода.

tasklist /FI "IMAGENAME eq notepad.exe" /FO CSV > search.log

FINDSTR notepad.exe search.log > found.log

FOR /F %%A IN (found.log) DO IF %%~zA EQU 0 GOTO end

start notepad.exe

:end

del search.log
del found.log

Я надеюсь, что это поможет кому-то другому.

Ответ 9

Мне нравятся инструменты WMIC и TASKLIST, но они недоступны в домашних/основных версиях окон. Другим способом является использование команды QPROCESS, доступной почти на всех машинах Windows (для тех, которые имеют терминальные службы - Я думаю, что только выиграть XP без SP2, так что практически каждый компьютер Windows):

@echo off
:check_process
setlocal
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running
set process_to_check=%~1
:: QPROCESS can display only the first 12 symbols of the running process
:: If other tool is used the line bellow could be deleted
set process_to_check=%process_to_check:~0,12%

QPROCESS * | find /i "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)
endlocal

QPROCESS команда не так сильна, как TASKLIST и ограничена отображением всего 12 символов имя процесса, но следует учитывать, если TASKLIST недоступно.

Более простое использование, когда оно использует имя, если процесс как аргумент (суффикс .exe является обязательным в этом случае, когда вы передаете исполняемое имя):

@echo off
:check_process
setlocal
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running
:: .exe suffix is mandatory
set "process_to_check=%~1"


QPROCESS "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)
endlocal

Различие между двумя способами использования QPROCESS заключается в том, что QPROCESS * отобразит все процессы, а QPROCESS some.exe будет фильтровать только процессы для текущего пользователя.

Использование WMI объектов через окна script host exe вместо WMIC также является опцией. Он должен также запускаться на всех машинах Windows (исключая те, где WSH выключен, но это редкий случай). Вот файл bat, который перечисляет все процессы через классы WMI и может использоваться вместо QPROCESS в script выше (это гибрид jscript/bat и должен быть сохранен как .bat):

@if (@X)==(@Y) @end /* JSCRIPT COMMENT **


@echo off
cscript //E:JScript //nologo "%~f0"
exit /b

************** end of JSCRIPT COMMENT **/


var winmgmts = GetObject("winmgmts:\\\\.\\root\\cimv2");
var colProcess = winmgmts.ExecQuery("Select * from Win32_Process");
var processes =  new Enumerator(colProcess);
for (;!processes.atEnd();processes.moveNext()) {
    var process=processes.item();
    WScript.Echo( process.processID + "   " + process.Name );
}

И модификация, которая будет проверять, запущен ли процесс:

@if (@X)==(@Y) @end /* JSCRIPT COMMENT **


@echo off
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running
set process_to_check=%~1

cscript //E:JScript //nologo "%~f0" | find /i "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)

exit /b

************** end of JSCRIPT COMMENT **/


var winmgmts = GetObject("winmgmts:\\\\.\\root\\cimv2");
var colProcess = winmgmts.ExecQuery("Select * from Win32_Process");
var processes =  new Enumerator(colProcess);
for (;!processes.atEnd();processes.moveNext()) {
    var process=processes.item();
    WScript.Echo( process.processID + "   " + process.Name );
}

Эти два параметра можно использовать на машинах без TASKLIST.

Конечная техника использует MSHTA. Это будет работать на всех машинах Windows с XP и выше и не зависит от настроек Windows script. вызов MSHTA может немного снизить производительность (опять же нужно сохранить как bat):

@if (@X)==(@Y) @end /* JSCRIPT COMMENT **
@echo off

setlocal
if "%~1" equ "" echo pass the process name as forst argument && exit /b 1
:: first argument is the process you want to check if running

set process_to_check=%~1


mshta "about:<script language='javascript' src='file://%~dpnxf0'></script>" | find /i "%process_to_check%" >nul 2>&1 && (
    echo process %process_to_check%  is running
) || (
    echo process %process_to_check%  is not running
)
endlocal
exit /b
************** end of JSCRIPT COMMENT **/


   var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);


   var winmgmts = GetObject("winmgmts:\\\\.\\root\\cimv2");
   var colProcess = winmgmts.ExecQuery("Select * from Win32_Process");
   var processes =  new Enumerator(colProcess);
   for (;!processes.atEnd();processes.moveNext()) {
    var process=processes.item();
    fso.Write( process.processID + "   " + process.Name + "\n");
   }
   close();

Ответ 10

Я не знаю, как это сделать со встроенным CMD, но если у вас grep, вы можете попробовать следующее:

tasklist /FI "IMAGENAME eq myApp.exe" | grep myApp.exe
if ERRORLEVEL 1 echo "myApp is not running"

Ответ 11

TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"

Ответ 12

Вы должны проверить имя родительского процесса, см. Статья кода о . NET-решение **.

Непрограммный способ проверки:

  • Запустить Cmd.exe
  • Запустить приложение (например, c:\windows\notepad.exe)
  • Проверьте свойства процесса Notepad.exe в Process Explorer
  • Проверить родительский процесс (показывает cmd.exe)

То же самое можно проверить, получив имя родительского процесса.

Ответ 13

Я предполагаю окна здесь. Таким образом, вам понадобится использовать WMI для получения этой информации. Ознакомьтесь с файлами для большого количества примеров того, как использовать WMI из script.

Ответ 14

Я использовал script, предоставленный Matt (2008-10-02). Единственное, с чем я столкнулся, это то, что он не удалит файл search.log. Я ожидаю, потому что мне пришлось cd в другое место, чтобы запустить мою программу. я cd 'd назад, где находятся BAT файл и search.log, но он все равно не будет удалять. Поэтому я решил, что сначала удалив файл search.log, а не последний.

del search.log

tasklist /FI "IMAGENAME eq myprog.exe" /FO CSV > search.log

FOR /F %%A IN (search.log) DO IF %%-zA EQU 0 GOTO end

cd "C:\Program Files\MyLoc\bin"

myprog.exe myuser mypwd

:end

Ответ 15

Я обычно выполняю следующую команду в приглашении cmd, чтобы проверить, работает ли файл program.exe или нет:

tasklist | grep program

Ответ 16

Просто отметив, что если ваше имя задачи действительно длинное, то оно не будет отображаться полностью в результате tasklist, поэтому было бы безопаснее (кроме локализации) проверять обратное.

Изменение этого ответа:

:: in case your task name is really long, check for the 'opposite' and find  the message when it not there
tasklist /fi "imagename eq yourreallylongtasknamethatwontfitinthelist.exe" 2>NUL | find /I /N "no tasks are running">NUL
if "%errorlevel%"=="0" (
    echo Task Found
) else (
    echo Not Found Task
)

Ответ 17

Основываясь на ответе vtrz и ответ Самуэля Ренкерта по другой теме, я придумал следующее script, который работает только %EXEC_CMD%, если он еще не запущен:

@echo off
set EXEC_CMD="rsync.exe"
wmic process where (name=%EXEC_CMD%) get commandline | findstr /i %EXEC_CMD%> NUL
if errorlevel 1 (
    %EXEC_CMD% ...
) else (
    @echo not starting %EXEC_CMD%: already running.
)

Как уже было сказано, для этого требуются административные привилегии.