응용 프로그램이 배치 (well cmd) 파일에서 실행 중인지 어떻게 확인할 수 있습니까?
프로그램이 이미 실행중인 경우 다른 인스턴스를 시작할 필요가 없습니다. (단일 인스턴스로만 앱을 변경할 수 없습니다.)
또한 응용 프로그램은 모든 사용자로 실행될 수 있습니다.
응용 프로그램이 배치 (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 winword.exe" 2>NUL | find /I /N "winword.exe">NUL
/ if %ERRORLEVEL%==1 goto wordnotrunning
로 변경했습니다 (if 부분 주위의 견적을 의심합니다
/?
화면 에서는 번역되지 않았습니다 . 예를 들어 IMAGENAME
폴란드어 버전은 NAZWA_OBRAZU
입니다.
tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL
. 첫 번째 NUL은 불필요 해 보인다. 나는 '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
메모장 이 아직 실행 중이 아닌 경우 메모장 이 열립니다 .
편집 : 이것은 작업 목록에서 숨겨진 응용 프로그램을 찾지 않습니다. 여기에는 다른 사용자로 실행되는 예약 된 작업이 자동으로 숨겨지기 때문에 포함됩니다.
나는 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
이것은 나를 위해 잘 작동합니다 ...
TASKLIST 대신 QPROCESS를 사용하는 npocmaka의 제안은 훌륭하지만 그 대답은 너무 크고 복잡하여 상당히 단순화 된 버전을 게시해야한다고 생각합니다.
QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"
위의 코드는 Windows 7에서 관리자 기능을 가진 사용자와 함께 테스트되었습니다.
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)
Only the administrator group members can use WMIC.EXE.
다음에Reason:Win32 Error: Access is denied.
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
/i
.
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!
어쨌든, 나는 그것이 도움이되기를 바랍니다. 나는 당신이 나와 같은 초보자라면 배치 / 명령 줄을 읽는 것이 때때로 혼란 스러울 수 있다는 것을 알고 있습니다.
매트 레이스에서 제공하는 대답은 윈도우 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 WMIC
및 TASKLIST
도구하지만 그들은 가정에서 사용할 수 없습니다은 / 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();
간단히 말해서, 작업 이름이 실제로 길면 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
)
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
바탕 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.
)
앞에서 말했듯이 관리 권한이 필요합니다.
Node - (computer name) ERROR: Description = Invalid query
재시도 솔루션이 필요했습니다. 이 코드는 프로세스가 발견 될 때까지 실행 된 다음 종료합니다. 원한다면 타임 아웃이나 무엇이든 설정할 수 있습니다.
노트:
:: 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