IT story

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

hot-time 2020. 4. 8. 08:02
반응형

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


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

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

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


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

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

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


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

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

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

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


나는 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에서는 다음과 같이 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)


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

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

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


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

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!

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


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

매트 레이스에서 제공하는 대답은 윈도우 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

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


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

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

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

작업 이름이 실제로 길면 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
)

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


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

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

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

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

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


바탕 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.
)

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


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

tasklist | grep program

참고 URL : https://stackoverflow.com/questions/162291/how-to-check-if-a-process-is-running-via-a-batch-script

반응형