source

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

factcode 2023. 4. 19. 23:31
반응형

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

응용 프로그램이 배치(well cmd) 파일에서 실행 중인지 확인하려면 어떻게 해야 합니까?

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

또, 애플리케이션을 임의의 유저로서 실행할 수도 있습니다.

GREP를 사용하여 파일을 저장할 필요가 없는 또 다른 가능성은 다음과 같습니다.

tasklist /fi "ImageName eq MyApp.exe" /fo csv 2>NUL | find /I "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Program is running
  • /fi ""이*. name입니다.*.exe로 하다
  • /fo csv은, 로는, 「」와 하지 않는 가 있기 때문입니다.이것은 기본적으로 실행 파일의 이름이 너무 길면 잘릴 수 있기 때문입니다.따라서, 다음과 같이 일치하지 않습니다.find
  • find /I하지 않는 할 수 .

전체 구문에 대해서는 tasklist 명령어 man 페이지를 참조하십시오.

제가 알아낸 방법은 다음과 같습니다.

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

위의 메모장이 아직 실행되지 않은 경우 열립니다.

편집: 작업 목록에서 숨겨진 응용 프로그램은 검색되지 않습니다.여기에는 다른 사용자로 실행되는 스케줄링된 작업이 모두 포함됩니다. 이러한 작업은 자동으로 숨겨집니다.

난 혼돈 마스터의 솔루션이 좋아!다만, 다른 외부 프로그램(find.exe 나 findstr.exe 등)을 기동하지 않는 솔루션을 찾고 있었습니다.그래서 저는 Matt Lacey의 솔루션 아이디어를 추가했습니다.그것은 피할 수 있는 임시 파일도 만듭니다.결국엔 꽤 간단한 해결책을 찾을 수 있었고, 그래서 그걸 공유했지...

SETLOCAL EnableExtensions
set EXE=MyProg.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF NOT %%x == %EXE% (
  echo %EXE% is Not Running
)

이게 나한테 잘 먹히는데...

위의 내용은 편집본입니다.원래 코드에는 GOTO가 들어있었고 댓글에 있는 누군가가 무례하다고 생각했다.

스페이스

프로그램 이름에 공백이 있는 경우 코드를 약간 복잡하게 만들어야 합니다.

SETLOCAL EnableExtensions
set EXE=My Prog.exe
FOR /F %%x IN ("%EXE%") do set EXE_=%%x
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF NOT %%x == %EXE_% (
  echo %EXE% is Not Running
)

실행 중인 다른 프로세스의 이름에 공백이 있는지 여부에 관계없이 원래 코드는 정상적으로 작동합니다.유일한 관심사는 우리가 목표로 하는 프로세스에 공간이 있는지 여부입니다.

또 다른

ELSE 절을 추가하면 이미 실행 중인 응용 프로그램의 모든 인스턴스에 대해 한 번 실행됩니다.이 스크립트를 실행할 때 실행 중인 인스턴스가 1개뿐이라는 보장은 없습니다.

필요한 경우 GOTO 또는 플래그 변수가 표시됩니다.

여러 인스턴스를 방지하기 위해 대상 응용 프로그램이 이미 뮤텍스되어 있는 것이 이상적이지만, 이는 다른 SO 질문의 주제이며 이 질문의 주제에는 해당되지 않습니다.

또 GOTO

저는 "ELSE" 코멘트에 동의합니다.GOTO-less 솔루션의 문제, 즉 조건 부분(및 ELSE 부분)을 여러 번 실행할 수 있기 때문에 루프를 종료해야 하기 때문에 조금 복잡합니다.(죄송합니다만, SPACE의 문제는 매우 드물기 때문에 여기서 취급하지 않습니다.)

SETLOCAL EnableExtensions
SET EXE=MyProg.exe
REM for testing
REM SET EXE=svchost.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF NOT %%x == %EXE% (
  ECHO %EXE% is Not Running
  REM This GOTO may be not necessary
  GOTO notRunning
) ELSE (
  ECHO %EXE is running
  GOTO Running
)
...
:Running
REM If Running label not exists, it will loop over all found tasks

TASKLIST 대신 QPROCESS를 사용하자는 npocmaka의 제안은 훌륭하지만, 답변이 너무 크고 복잡하기 때문에 상당히 단순화된 버전을 게시해야 할 의무가 있습니다.이것에 의해, 상급 유저가 아닌 유저의 문제가 해결된다고 생각합니다.

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

위의 코드는 관리자 권한을 가진 사용자를 사용하여 Windows 7에서 테스트되었습니다.

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

윈도우즈에서 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)

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!

어쨌든 도움이 됐으면 좋겠어요.나처럼 초보일 경우 배치/명령줄을 읽는 것이 때때로 혼란스러울 수 있다는 것을 알고 있습니다.

Program Files\에 설치된 http://www.teamcti.com/pview/prcview.htm의 PV.exe를 사용합니다.다음과 같은 배치 파일이 있는 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

Matt Lacey가 제공한 답변은 Windows 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

이게 다른 사람에게 도움이 됐으면 좋겠어요.

는 음에들이 에 들어요.WMIC ★★★★★★★★★★★★★★★★★」TASKLIST툴은 홈 에디션/베이직 에디션에서는 사용할 수 없습니다. 하나의 은 '보다 낫다'입니다.QPROCESS명령어는 거의 모든 Windows 머신에서 사용할 수 있습니다(단말기 서비스가 있는 경우에는 SP2가 없는 XP에서만 사용할 수 있으므로 모든 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 exe가 아닌 WMIC또한 옵션입니다.모든 윈도 머신(WSH가 꺼진 머신 제외)에서도 실행되어야 합니다(이것은 드문 경우입니다). 모든 하고 WMI 대신 할 수 입니다.QPROCESS에서는 (로 "jscript/bat" (jscript/bat "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 );
}

두 가지 the the 、 the the 、 the 、 the 、 the 、 the 、 the 、 the 、 the 、 the 、 the 、 the 。TASKLIST

은 '아예'를 사용하는 입니다.MSHTAXP 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
)

같은 이름의 .exe 파일이 여러 개 있고 그 중 하나만 체크하는 경우(예: C:\My Project\bin\release\My Application.C가 아닌 exe:\MyProject\bin\debug\MyApplication.exe)를 사용하면 다음 항목을 사용할 수 있습니다.

@echo off

set "workdir=C:\MyProject\bin\release"
set "workdir=%workdir:\=\\%"

setlocal enableDelayedExpansion
for /f "usebackq tokens=* delims=" %%a in (`
    wmic process  where 'CommandLine like "%%!workdir!%%" and not CommandLine like "%%RuntimeBroker%%"'   get CommandLine^,ProcessId  /format:value
`) do (
    for /f "tokens=* delims=" %%G in ("%%a")  do (
        if "%%G" neq "" (
rem            echo %%G
            set "%%G"
rem            echo !ProcessId!
            goto :TheApplicationIsRunning
        )
    )
) 

echo The application is not running
exit /B

:TheApplicationIsRunning
echo The application is running
exit /B

나는 재시도할 수 있는 해결책이 필요했다.이 코드는 프로세스가 검출된 후 종료될 때까지 실행됩니다.타임아웃 같은 것을 설정할 수 있습니다.

주의:

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

여기 창문이 있는 것 같은데따라서 이 정보를 얻으려면 WMI를 사용해야 합니다.스크립트에서 WMI를 사용하는 방법에 대한 많은 예제를 보려면 스크립팅 담당자의 아카이브를 확인하십시오.

Matt(2008-10-02)가 제공한 스크립트를 사용했습니다.내가 유일하게 문제가 된 것은 그것이 그 파일을 삭제하지 않는다는 것이다.search.log 것 요. 예합니왜왜cd다른 곳으로 이동하여 프로그램을 시작합니다.cd and BAT ' (BAT 파일과 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

vtrz의 답변과 Samuel Renkert의 답변이 다른 토픽에 기반하여 다음과 같은 실행 스크립트만 생각해냈습니다.%EXEC_CMD%"CHANGE: "CHANGE: " 。

@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 프롬프트에서 다음 명령을 실행하여 프로그램이 있는지 확인합니다.exe 실행 여부:

tasklist | grep program

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

비프로그래밍 방식으로 다음 사항을 확인합니다.

  1. Cmd.exe를 기동합니다.
  2. 애플리케이션을 기동합니다(예를 들면,c:\windows\notepad.exe)
  3. 메모장의 속성을 확인합니다.프로세스 탐색기의 exe 프로세스
  4. 상위 프로세스 확인(cmd.exe 표시)

부모 프로세스명을 취득하는 것으로, 같은 것을 확인할 수 있습니다.

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

반응형