Làm cách nào để kiểm tra xem một tiến trình có đang chạy qua tập lệnh bó không


260

Làm cách nào để kiểm tra xem ứng dụng có chạy từ tệp bó (cũng cmd) không?

Tôi cần không khởi chạy một thể hiện khác nếu một chương trình đang chạy. (Tôi không thể thay đổi ứng dụng để chỉ tạo một ứng dụng.)

Ngoài ra ứng dụng có thể chạy như bất kỳ người dùng nào.



12
trùng lặp một câu hỏi năm năm sau?
Matt Lacey

@ LưuViênPhúc họ thậm chí không tương đối gần.
Đức Hồng Y - Phục hồi Monica

@JackKirby ai nói rằng nó không liên quan?
phuclv

Câu trả lời:


330

Một khả năng khác tôi nghĩ ra, lấy cảm hứng từ việc sử dụng grep , là:

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

Nó không cần phải lưu thêm một tập tin, vì vậy tôi thích phương pháp này.


7
cái này hoạt động tốt với tôi (windows XP SP3). IMHO đây là cách thanh lịch nhất trong tất cả các đề xuất ở đây, chỉ sử dụng các công cụ được vận chuyển có cửa sổ
hello_earth

2
Tôi đã có vấn đề cú pháp với dòng lệnh này. Tôi đã thay đổi nó thành tasklist /FI "IMAGENAME eq winword.exe" 2>NUL | find /I /N "winword.exe">NUL/ if %ERRORLEVEL%==1 goto wordnotrunningđể làm cho nó hoạt động (nghi ngờ trích dẫn xung quanh phần if
Steve B

4
Xin nhớ rằng trong các phiên bản ngôn ngữ khác của XP, tên bộ lọc được dịch theo mã nhưng không phải trong /?màn hình trợ giúp . Vì vậy, ví dụ IMAGENAMEtrong phiên bản đánh bóng là NAZWA_OBRAZU.
rsk82

3
Trong Win7, tôi đã phải đổi nó thành tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL NUL đầu tiên có vẻ không cần thiết, tôi không biết '2' dùng để làm gì, / NH là tùy chọn.
Jan Doggen

12
danh sách tác vụ luôn thoát với trạng thái 0 cho dù nó có tìm thấy bất kỳ tác vụ phù hợp nào hay không, đó là lý do tại sao nó vô dụng. Vì dù sao bạn cũng phải sử dụng find (hoặc findstr) để kiểm tra đầu ra của nó, nên không có điểm nào sử dụng bộ lọc của danh sách tác vụ. Chỉ cần làm danh sách nhiệm vụ | tìm "myprog.exe"> nul: && goto Foundit hoặc somesuch. Bạn có thể cần tùy chọn / v (verbose) cho danh sách tác vụ.
Denis Howe

61

Đây là cách tôi đã giải quyết nó:

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

Ở trên sẽ mở Notepad nếu nó chưa chạy.

Chỉnh sửa: Lưu ý rằng điều này sẽ không tìm thấy các ứng dụng ẩn khỏi danh sách tác vụ. Điều này sẽ bao gồm mọi tác vụ theo lịch trình đang chạy như một người dùng khác, vì chúng được ẩn tự động.


2
Thay đổi định dạng danh sách tác vụ thành CSV hoặc bất cứ thứ gì ngoại trừ bảng rất quan trọng vì bố cục mặc định của danh sách tác vụ (bảng) cắt ngắn tên hình ảnh dài phá vỡ logic.
Scott White

4
Giải pháp này sẽ không hoạt động trên Vista vì TASKLIST tạo ra một số đầu ra ngay cả khi không tìm thấy quy trình. Tôi đoán điều tương tự cũng đúng với Windows 7.
dbenham

không hoạt động trong Windows 10. search.log chứa "INFO: Không có tác vụ nào đang chạy phù hợp với tiêu chí đã chỉ định." và không có notepad được bắt đầu
Sergey

46

Tôi thích giải pháp của Chaosmaster! Nhưng tôi đã tìm một giải pháp không khởi động một chương trình bên ngoài khác (như find.exe hoặc findstr.exe ). Vì vậy, tôi đã thêm ý tưởng từ giải pháp Matt Lacey, tạo ra một tệp tạm thời cũng có thể tránh được. Cuối cùng, tôi có thể tìm thấy một giải pháp khá đơn giản, vì vậy tôi chia sẻ nó ...

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

Điều này đang làm việc tốt cho tôi ...


Giải pháp này hoạt động tốt - được thử nghiệm trong Windows 8.1. Tôi đã nhận thấy rằng nó là trường hợp nhạy cảm.
oliver-clare

@LordScree Khi tôi làm việc trên hệ thống un * x độ nhạy trường hợp là tốt cho tôi! Tôi thậm chí còn thiết lập hệ thống tệp để kích hoạt tên tệp phân biệt chữ hoa chữ thường. ;)
TrueY

Hoạt động tốt đối với tôi - đã thử nghiệm trong windows 7 X64
Mr Rubix

Điều này không hoạt động nếu ứng dụng có một khoảng trắng trong tên vì% x kết thúc là một phần của tên ứng dụng cho đến không gian đầu tiên.
Chris

Một giải pháp khả thi sẽ là kiểm tra xem ứng dụng có được tìm thấy hay không bằng cách kiểm tra xem% x == INFO: nhưng tôi không biết phiên bản Windows nào sẽ hoạt động trên hoặc nếu có giải pháp tốt hơn.
Chris

21

Đề xuất của npocmaka sử dụng QPROCESS thay vì TASKLIST là rất tốt, nhưng, câu trả lời của nó quá lớn và phức tạp đến nỗi tôi cảm thấy bắt buộc phải đăng một phiên bản khá đơn giản của nó, theo tôi đoán, sẽ giải quyết vấn đề của hầu hết người dùng không nâng cao:

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

Mã ở trên đã được thử nghiệm trong Windows 7, với một người dùng có độ cứng quản trị viên.


Tôi chỉ sử dụng ý tưởng này để ngăn chặn một quá trình tự động bắn hai lần và nó hoạt động như một cơ duyên!
Davy C

Tôi phải nói rằng không giống như lệnh này, các giải pháp danh sách tác vụ không chỉ trông quá phức tạp đối với một truy vấn đơn giản như vậy, mà chúng còn chạy một giây hoặc lâu hơn và sử dụng hàng tấn cpu! Điều này tốt hơn nhiều, cũng hoạt động mà không có quyền quản trị (Windows Server 2012).
Eugene Marin

Đây dường như là giải pháp đơn giản và tốt nhất (ít nhất là đối với tôi) vì nó hoạt động như hiện tại khi ứng dụng có khoảng trắng trong tên. Tôi tò mò không biết giới hạn của giải pháp này là gì và tại sao nó không có nhiều phiếu bầu hơn.
Chris

20

Trong Windows, bạn có thể sử dụng Công cụ quản lý Windows (WMI) để đảm bảo rằng không có ứng dụng nào có dòng lệnh được chỉ định được khởi chạy, ví dụ:

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)


Lưu ý rằng WMIC yêu cầu đặc quyền quản trị; nếu bạn không có nó, thì Only the administrator group members can use WMIC.EXE.tiếp theo làReason:Win32 Error: Access is denied.
Jeroen Wiert Pluimers

Tôi nghĩ rằng đây là giải pháp tốt nhất, bởi vì wmic cung cấp cho bạn một dòng lệnh hoàn chỉnh được đưa ra và hàng triệu thông tin khác ...
Glavić

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

3
Điều này thực sự hoạt động tuyệt vời. Đơn giản! Chỉ cần lưu ý rằng trường hợp nhạy cảm trừ khi bạn thêm /i.
Jason

8

Tôi sử dụng PV.exe từ http://www.teamcti.com/pview/prcview.htmlm được cài đặt trong Chương trình Tệp \ PV với một tệp bó như thế này:

@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
cái này hoạt động với tôi trên windows 7. Dòng thứ 2 là thư mục chứa chương trình, không phải chương trình.
Fabio Cionini

8

Câu trả lời của TrueY có vẻ là giải pháp tao nhã nhất, tuy nhiên, tôi đã phải làm một vài điều lộn xộn vì tôi không hiểu chính xác chuyện gì đang xảy ra. Hãy để tôi làm rõ mọi thứ để hy vọng tiết kiệm thời gian cho người tiếp theo.

Câu trả lời được sửa đổi của 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!

Dù sao, tôi hy vọng rằng sẽ giúp. Tôi biết đôi khi đọc lô / dòng lệnh đôi khi có thể gây nhầm lẫn nếu bạn là người mới, như tôi.


6

Câu trả lời được cung cấp bởi Matt Lacey hoạt động cho Windows XP. Tuy nhiên, trong Windows Server 2003, dòng

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

trả lại

THÔNG TIN: Không có tác vụ nào đang chạy phù hợp với tiêu chí đã chỉ định.

mà sau đó được đọc khi quá trình đang chạy.

Tôi không có nhiều kinh nghiệm về kịch bản hàng loạt, vì vậy, tâm lý của tôi là sau đó tìm kiếm tên quy trình trong search.logtệp và bơm kết quả vào một tệp khác và tìm kiếm bất kỳ đầu ra nào.

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

Tôi mong điều này giúp được người nào khác.


Điều này hoạt động cho Win 2008. +1 cho Không có tác vụ nào đang chạy phù hợp với tiêu chí đã chỉ định.
Mangesh Pimpalkar

5

Tôi thích các công cụ WMICTASKLISTcông cụ nhưng chúng không có sẵn trong các phiên bản cơ bản / gia đình của QPROCESSwindows. Cách khác là sử dụng lệnh có sẵn trên hầu hết mọi máy Windows (đối với những máy có dịch vụ đầu cuối - tôi nghĩ chỉ thắng XP mà không có SP2, vì vậy thực tế là mọi máy tính cửa sổ):

@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

QPROCESSlệnh không quá mạnh TASKLISTvà bị giới hạn khi chỉ hiển thị 12 ký hiệu của tên tiến trình nhưng nên được xem xét nếu TASKLISTkhông có sẵn.

Cách sử dụng đơn giản hơn trong đó nó sử dụng tên nếu quy trình làm đối số ( .exehậu tố là bắt buộc trong trường hợp này khi bạn chuyển tên thực thi):

@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

Sự khác biệt giữa hai cách QPROCESSsử dụng là ý QPROCESS *chí sẽ liệt kê tất cả các quy trình trong khi QPROCESS some.exesẽ chỉ lọc các quy trình cho người dùng hiện tại.

Sử dụng WMIcác đối tượng thông qua windows script exe thay vì WMICcũng là một tùy chọn. Nó cũng nên chạy trên mọi máy windows (không bao gồm các đối tượng mà WSH bị tắt nhưng đây là trường hợp hiếm gặp). Đây là tệp bat liệt kê tất cả các quy trình thông qua WMI các lớp và có thể được sử dụng thay vì QPROCESStrong tập lệnh ở trên (nó là một jscript / bat hybrid và nên được lưu dưới dạng .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 );
}

Và một sửa đổi sẽ kiểm tra nếu một quá trình đang chạy:

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

Hai tùy chọn có thể được sử dụng trên các máy không có TASKLIST.

Kỹ thuật cuối cùng là sử dụng MSHTA. Điều này sẽ chạy trên mọi máy Windows từ XP trở lên và không phụ thuộc vào cài đặt máy chủ tập lệnh windows. cuộc gọi của MSHTAcó thể làm giảm một chút hiệu suất mặc dù (một lần nữa nên được lưu dưới dạng 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();

2

Tôi không biết làm thế nào để làm như vậy với tích hợp sẵn trong CMD nhưng nếu bạn có grep, bạn có thể thử các cách sau:

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

2

Chỉ cần đề cập, nếu tên nhiệm vụ của bạn thực sự dài thì nó sẽ không xuất hiện hoàn toàn trong tasklistkết quả, do đó có thể an toàn hơn (ngoài nội địa hóa) để kiểm tra ngược lại.

Sự thay đổi của câu trả lời này :

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

Tôi đang giả sử cửa sổ ở đây. Vì vậy, bạn sẽ cần sử dụng WMI để có được thông tin đó. Kiểm tra tài liệu lưu trữ của The Scripting Guy để biết rất nhiều ví dụ về cách sử dụng WMI từ tập lệnh.


0

Tôi đã sử dụng tập lệnh được cung cấp bởi Matt (2008-10-02). Điều duy nhất tôi gặp rắc rối là nó sẽ không xóa search.logtập tin. Tôi mong đợi vì tôi phải cdđến một địa điểm khác để bắt đầu chương trình của mình. Tôi cdđã quay lại vị trí của tệp BAT search.log, nhưng nó vẫn không xóa. Vì vậy, tôi đã giải quyết điều đó bằng cách xóa search.logtập tin trước thay vì cuối cùng.

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: Có thêm một chút thông tin được thêm vào đây, vì vậy tôi có xu hướng để lại như một câu trả lời.
Lập hóa đơn cho Thằn lằn

0

Bạn nên kiểm tra tên tiến trình cha, xem bài viết Dự án mã về giải pháp dựa trên .NET ** .

Một cách không lập trình để kiểm tra:

  1. Khởi chạy Cmd.exe
  2. Khởi chạy một ứng dụng (ví dụ, c:\windows\notepad.exe)
  3. Kiểm tra các thuộc tính của quy trình Notepad.exe trong Process Explorer
  4. Kiểm tra tiến trình cha (Điều này hiển thị cmd.exe)

Điều tương tự có thể được kiểm tra bằng cách lấy tên tiến trình cha.


0

Dựa trên câu trả lời của vtrzcâu trả lời của Samuel Renkert về một chủ đề khác , tôi đã đưa ra đoạn script sau chỉ chạy %EXEC_CMD%nếu nó chưa chạy:

@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.
)

Như đã nói trước đây, điều này đòi hỏi đặc quyền hành chính.


đã không làm việc cho tôi và tôi đang sử dụng tài khoản quản trị viên. Một hộp DOS xuất hiện cùng vớiNode - (computer name) ERROR: Description = Invalid query
khaverim

1
Hoạt động tốt cho tôi.
Đánh dấu Duncan

1
Hoạt động tuyệt vời cho Windows 7 tại đây. Không vấn đề.
galacticninja

0

Tôi cần một giải pháp với thử lại. Mã này sẽ chạy cho đến khi quá trình được tìm thấy và sau đó giết nó. Bạn có thể đặt thời gian chờ hoặc bất cứ điều gì nếu bạn muốn.

Ghi chú:

  • ".Exe" là bắt buộc
  • Bạn có thể tạo một tệp có thể chạy được với các tham số, phiên bản bên dưới
    :: 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
        )

Chạy với .\taskkill.bat ProgramToKill.exe


-2

Tôi thường thực hiện lệnh sau trong dấu nhắc cmd để kiểm tra xem chương trình của tôi có chạy hay không:

tasklist | grep program
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.