배치 스크립트를 통해 프로세스가 실행 중인지 확인하는 방법


260

응용 프로그램이 배치 (well cmd) 파일에서 실행 중인지 어떻게 확인할 수 있습니까?

프로그램이 이미 실행중인 경우 다른 인스턴스를 시작할 필요가 없습니다. (단일 인스턴스로만 앱을 변경할 수 없습니다.)

또한 응용 프로그램은 모든 사용자로 실행될 수 있습니다.



12
5 년 후 질문이 중복 되었습니까?
Matt Lacey

@ LưuVĩnhPhúc 그들은 상대적으로 가깝지 않습니다.
추기경-복원 모니카

@JackKirby 누가 관련이 없다고 말했습니까?
phuclv

답변:


330

grep 을 사용하여 영감을 얻은 또 다른 가능성은 다음과 같습니다.

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

추가 파일을 저장할 필요가 없으므로이 방법을 선호합니다.


7
이것은 나를 위해 잘 작동했습니다 (Windows XP SP3). IMHO 이것은 Windows와 함께 제공된 도구를 사용하여 여기에서 제안 된 가장 우아한 방법입니다
hello_earth

2
이 명령 줄에 구문 문제가있었습니다. 나는 그것을 작동시키기 위해 tasklist /FI "IMAGENAME eq winword.exe" 2>NUL | find /I /N "winword.exe">NUL/ if %ERRORLEVEL%==1 goto wordnotrunning로 변경했습니다 (if 부분 주위의 견적을 의심합니다
Steve B

4
XP의 다른 언어 버전에서는 필터 이름이 코드로 번역되었지만 도움말 /?화면 에서는 번역되지 않았습니다 . 예를 들어 IMAGENAME폴란드어 버전은 NAZWA_OBRAZU입니다.
rsk82

3
Win7에서 나는 그것을 변경해야했다 tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL . 첫 번째 NUL은 불필요 해 보인다. 나는 '2'가 무엇인지 전혀 모른다.
Jan Doggen

12
tasklist는 일치하는 작업을 찾을 수 있는지 여부에 관계없이 항상 상태 0으로 종료되므로 자체적으로 쓸모가 없습니다. 어쨌든 find (또는 findstr)를 사용하여 출력을 확인해야하므로 작업 목록의 필터를 사용하는 것이 중요하지 않습니다. 그냥 작업 목록을 수행 | "myprog.exe"> nul : && goto foundit 또는 기타를 찾으십시오. tasklist에 / v (verbose) 옵션이 필요할 수 있습니다.
Denis Howe

61

내가 그것을 해결 한 방법은 다음과 같습니다.

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

메모장 이 아직 실행 중이 아닌 경우 메모장 이 열립니다 .

편집 : 이것은 작업 목록에서 숨겨진 응용 프로그램을 찾지 않습니다. 여기에는 다른 사용자로 실행되는 예약 된 작업이 자동으로 숨겨지기 때문에 포함됩니다.


2
작업 목록 형식을 CSV 또는 표 이외의 형식으로 변경하면 작업 목록 기본 레이아웃 (테이블)이 긴 이미지 이름을 잘라 논리를 깨뜨 리므로 중요합니다.
Scott White

4
TASKLIST는 프로세스를 찾을 수없는 경우에도 일부 출력을 생성하므로이 솔루션은 Vista에서 작동하지 않습니다. Windows 7에서도 마찬가지입니다.
dbenham

Windows 10에서 작동하지 않습니다. search.log에 "INFO : 지정된 기준과 일치하는 작업이 실행되고 있지 않습니다." 더 메모장이 시작되지 않습니다
세르게이

46

나는 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

이것은 나를 위해 잘 작동합니다 ...


이 솔루션은 Windows 8.1에서 잘 테스트되었습니다. 대소 문자를 구분한다는 것을 알았습니다.
oliver-clare

@LordScree un * x 시스템에서 작업 할 때 대소 문자 구분이 나에게 좋습니다! 대소 문자를 구분하는 파일 이름을 사용하도록 파일 시스템을 설정했습니다. ;)
TrueY

Windows 7 X64에서 테스트되었습니다
Mr Rubix

% x에 응용 프로그램 이름의 일부가 첫 번째 공간이되어 응용 프로그램에 이름에 공백이 있으면 작동하지 않습니다.
Chris

가능한 해결책은 % x == INFO :를 확인하여 대신 응용 프로그램을 찾을 수 없는지 확인하는 것이지만 어떤 Windows 버전이 작동하는지 또는 더 나은 솔루션이 있는지 모르겠습니다.
Chris

21

TASKLIST 대신 QPROCESS를 사용하는 npocmaka의 제안은 훌륭하지만 그 대답은 너무 크고 복잡하여 상당히 단순화 된 버전을 게시해야한다고 생각합니다.

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

위의 코드는 Windows 7에서 관리자 기능을 가진 사용자와 함께 테스트되었습니다.


방금이 아이디어를 사용하여 자동화 된 프로세스 실행을 두 번 중지했으며 매력처럼 작동했습니다!
Davy C

이 명령과 달리 작업 목록 솔루션은 이러한 간단한 쿼리에는 너무 복잡해 보일뿐만 아니라 1 초 정도 실행되어 수많은 CPU를 사용한다고 말해야합니다. 이것은 훨씬 더 좋고, 관리자 권한 없이도 작동했습니다 (Windows Server 2012).
유진 마린

이것은 응용 프로그램의 이름에 공백이있을 때 그대로 작동하는 가장 단순하고 최상의 솔루션 인 것 같습니다 (적어도 나에게는). 이 솔루션의 한계가 무엇인지, 왜 더 많은 투표권이 없는지 궁금합니다.
Chris

20

Windows에서는 다음과 같이 WMI (Windows Management Instrumentation)를 사용하여 지정된 명령 줄이있는 앱이 시작되지 않도록 할 수 있습니다.

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)


WMIC에는 관리자 권한이 필요합니다. 당신이 그것을하지 않으면 Only the administrator group members can use WMIC.EXE.다음에Reason:Win32 Error: Access is denied.
Jeroen Wiert Pluimers

wmic은 당신에게 완전한 명령 행을 제공하고 다른 정보를 milion로 제공하기 때문에 이것이 최선의 해결책이라고 생각합니다.
Glavić

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

3
이것은 실제로 훌륭하게 작동합니다. 단순한! 를 추가하지 않으면 대소 문자를 구분합니다 /i.
Jason

8

Program Files \ PV에 설치된 http://www.teamcti.com/pview/prcview.htm의 PV.exe를 다음 과 같은 배치 파일과 함께 사용합니다.

@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

1
이것은 Windows 7에서 저에게 효과적입니다. 두 번째 줄은 프로그램 자체가 아니라 프로그램을 포함하는 디렉토리입니다.
Fabio Cionini

8

TrueY의 대답은 가장 우아한 해결책으로 보였지만 정확히 무슨 일이 일어나고 있는지 이해하지 못했기 때문에 혼란스러워해야했습니다. 다음 사람을 위해 시간을 절약 할 수 있도록 정리해 보겠습니다.

TrueY의 수정 된 답변 :

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

어쨌든, 나는 그것이 도움이되기를 바랍니다. 나는 당신이 나와 같은 초보자라면 배치 / 명령 줄을 읽는 것이 때때로 혼란 스러울 수 있다는 것을 알고 있습니다.


6

매트 레이스에서 제공하는 대답은 윈도우 XP에 적용됩니다. 그러나 Windows Server 2003에서는

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

보고

정보 : 지정된 기준과 일치하는 작업이 실행되고 있지 않습니다.

그런 다음 프로세스가 실행 중일 때 읽 힙니다.

일괄 스크립팅 경험이 없기 때문에 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

나는 이것이 다른 누군가를 돕기를 바랍니다.


이것은 Win 2008에서 작동합니다. +1 지정된 작업과 일치하는 작업이 실행되고 있지 않습니다.
Mangesh Pimpalkar

5

등 I WMICTASKLIST도구하지만 그들은 가정에서 사용할 수 없습니다은 / windows.Another 방법의 기본 버전이 사용하는 QPROCESS터미널 서비스를 가지고있는 것들에 대한 (거의 모든 윈도우 시스템에서 사용할 수있는 명령을 - 난 단지 생각 SP2없이 XP에서 승리, 그래서 practialy 모든 윈도우 머신) :

@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대신 Windows 스크립트 호스트 exe를 통해 개체를 사용 WMIC하는 것도 옵션입니다 .WSH가 꺼져 있지만 드문 경우는 아니지만 모든 Windows 컴퓨터에서도 실행해야합니다 .WMI를 통해 모든 프로세스를 나열하는 bat 파일 QPROCESS위의 스크립트 대신 클래스를 사용할 수 있습니다 (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있습니다. 이것은 XP 이상의 모든 Windows 시스템에서 실행되며 Windows 스크립트 호스트 설정에 의존하지 않습니다. 호출은 MSHTA성능을 약간 떨어 뜨릴 수 있습니다 (다시 박쥐로 저장해야 함).

@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();

2

내장 CMD로 그렇게하는 방법을 모르겠지만 grep이 있으면 다음을 시도해보십시오.

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

2

간단히 말해서, 작업 이름이 실제로 길면 tasklist결과에 전체적으로 표시되지 않으므로 반대를 확인하는 것이 더 안전 할 수 있습니다 (현지화 제외).

이 답변의 변형 :

:: in case your task name is really long, check for the 'opposite' and find  the message when it's 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
)

0

나는 여기서 창문을 가정하고 있습니다. 따라서 해당 정보를 얻으려면 WMI를 사용해야합니다. 스크립트에서 WMI를 사용하는 방법에 대한 많은 예제는 Scripting Guy의 아카이브 를 확인하십시오 .


0

Matt (2008-10-02)에서 제공 한 스크립트를 사용했습니다 . 내가 문제가 된 유일한 것은 search.log파일을 삭제하지 않는다는 것 입니다. cd프로그램을 시작하려면 다른 위치로 가야했기 때문 입니다. I cd'd 개의 박쥐 파일과 위치를 다시 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

1
@ Sebastian : 여기에 약간의 추가 정보가 추가되어 있으므로 답으로 남겨 두는 경향이 있습니다.
Bill the Lizard

0

상위 프로세스 이름을 확인해야합니다 . .NET 기반 솔루션 에 대한 코드 프로젝트 기사 **를 참조하십시오 .

프로그래밍 방식이 아닌 확인 방법 :

  1. Cmd.exe 실행
  2. (예를 들어 응용 프로그램을 실행 c:\windows\notepad.exe)
  3. 프로세스 탐색기 에서 Notepad.exe 프로세스의 속성 확인
  4. 부모 프로세스 확인 (cmd.exe가 표시됨)

부모 프로세스 이름을 가져와 동일한 사항을 확인할 수 있습니다.


0

바탕 vtrz의 대답타 주제에 사무엘 Renkert의 대답 , 난 단지 실행 다음 스크립트를 내놓았다 %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.
)

앞에서 말했듯이 관리 권한이 필요합니다.


나를 위해 작동하지 않았고 관리자 계정을 사용하고 있습니다. DOS 상자가 나타납니다Node - (computer name) ERROR: Description = Invalid query
khaverim

1
나를 위해 잘 작동합니다.
Mark Duncan

1
여기에서 Windows 7에 적합합니다. 문제 없습니다.
galacticninja

0

재시도 솔루션이 필요했습니다. 이 코드는 프로세스가 발견 될 때까지 실행 된 다음 종료합니다. 원한다면 타임 아웃이나 무엇이든 설정할 수 있습니다.

노트:

  • ".exe"는 필수입니다
  • 아래 버전의 매개 변수로 파일을 실행 가능하게 만들 수 있습니다.
    :: Set programm you want to kill
    :: Fileextension is mandatory
    SET KillProg=explorer.exe

    :: Set waiting time between 2 requests in seconds
    SET /A "_wait=3"

    :ProcessNotFound
        tasklist /NH /FI "IMAGENAME eq %KillProg%" | FIND /I "%KillProg%"
        IF "%ERRORLEVEL%"=="0" (
            TASKKILL.EXE /F /T /IM %KillProg%
        ) ELSE (
            timeout /t %_wait%
            GOTO :ProcessNotFound
        )

taskkill.bat:

    :: Get program name from argumentlist
    IF NOT "%~1"=="" (
        SET "KillProg=%~1"
    ) ELSE (
        ECHO Usage: "%~nx0" ProgramToKill.exe & EXIT /B
    )

    :: Set waiting time between 2 requests in seconds
    SET /A "_wait=3"

    :ProcessNotFound
        tasklist /NH /FI "IMAGENAME eq %KillProg%" | FIND /I "%KillProg%"
        IF "%ERRORLEVEL%"=="0" (
            TASKKILL.EXE /F /T /IM %KillProg%
        ) ELSE (
            timeout /t %_wait%
            GOTO :ProcessNotFound
        )

로 실행 .\taskkill.bat ProgramToKill.exe


-2

일반적으로 cmd 프롬프트에서 다음 명령을 실행하여 program.exe가 실행 중인지 확인합니다.

tasklist | grep program
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.