Cara memeriksa apakah suatu proses berjalan melalui skrip batch

260

Bagaimana saya bisa memeriksa apakah aplikasi berjalan dari file batch (well cmd)?

Saya tidak perlu meluncurkan instance lain jika suatu program sudah berjalan. (Saya tidak bisa mengubah aplikasi untuk menjadikannya satu contoh saja.)

Juga aplikasi bisa berjalan seperti pengguna mana pun.

Matt Lacey
sumber
12
duplikat pertanyaan yang diajukan lima tahun kemudian?
Matt Lacey
@ LưuVĩnhPhúc mereka bahkan tidak cukup dekat.
Kardinal - Pasang kembali Monica
@ JackKirby yang mengatakan bahwa itu tidak terkait?
phuclv
3
@oopsdazie ya saya mungkin salah dalam kasus ini tetapi aturan umumnya adalah menyimpan pertanyaan dengan koleksi jawaban terbaik, dan menutup yang lain sebagai duplikat , terlepas dari waktu
phuclv

Jawaban:

330

Kemungkinan lain yang saya temukan, terinspirasi oleh penggunaan grep , adalah:

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

Tidak perlu menyimpan file tambahan, jadi saya lebih suka metode ini.

pkamb
sumber
7
ini bekerja dengan baik untuk saya (windows XP SP3). IMHO ini adalah cara paling elegan dari semua yang diusulkan di sini, hanya menggunakan alat yang dikirimkan dengan windows
hello_earth
2
Saya punya masalah sintaks dengan baris perintah ini. Saya mengubahnya ke tasklist /FI "IMAGENAME eq winword.exe" 2>NUL | find /I /N "winword.exe">NUL/ if %ERRORLEVEL%==1 goto wordnotrunninguntuk membuatnya berfungsi (mencurigai kutipan di sekitar bagian jika
Steve B
4
Harap diingat bahwa dalam versi bahasa XP lainnya nama filter diterjemahkan dalam kode tetapi tidak di /?layar bantuan . Jadi misalnya IMAGENAMEdalam versi polish adalah NAZWA_OBRAZU.
rsk82
3
Di bawah Win7 saya harus mengubahnya ke tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL NUL pertama tampaknya tidak perlu, saya tidak tahu untuk apa '2' itu, / NH adalah opsional.
Jan Doggen
12
daftar tugas selalu keluar dengan status 0 apakah menemukan tugas yang cocok atau tidak, itulah mengapa tidak berguna dengan sendirinya. Karena Anda harus menggunakan find (atau findstr) untuk memeriksa outputnya, tidak ada gunanya menggunakan filter daftar tugas. Lakukan saja daftar tugas | temukan "myprog.exe"> nul: && goto foundit atau semacamnya. Anda mungkin memerlukan opsi / v (verbose) ke daftar tugas.
Denis Howe
61

Inilah cara saya mengatasinya:

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

Di atas akan membuka Notepad jika belum berjalan.

Sunting: Perhatikan bahwa ini tidak akan menemukan aplikasi yang disembunyikan dari daftar tugas. Ini akan mencakup tugas terjadwal yang berjalan sebagai pengguna yang berbeda, karena ini disembunyikan secara otomatis.

Matt Lacey
sumber
2
Mengubah format daftar tugas ke CSV atau apa pun selain tabel adalah penting karena itu tugas default tata letak (tabel) memotong nama gambar panjang yang melanggar logika.
Scott White
4
Solusi ini tidak akan berfungsi pada Vista karena TASKLIST menghasilkan beberapa output bahkan jika prosesnya tidak ditemukan. Saya kira hal yang sama berlaku untuk Windows 7.
dbenham
tidak bekerja di Windows 10. search.log berisi "INFO: Tidak ada tugas yang berjalan yang cocok dengan kriteria yang ditentukan." dan tidak ada notepad dimulai
Sergey
46

Saya suka solusi Chaosmaster! Tapi saya mencari solusi yang tidak memulai program eksternal lain (seperti find.exe atau findstr.exe ). Jadi saya menambahkan ide dari solusi Matt Lacey, yang membuat file temp juga dapat dihindari. Pada akhirnya saya bisa menemukan solusi yang cukup sederhana, jadi saya membagikannya ...

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

Ini bekerja untuk saya dengan baik ...

Benar
sumber
Solusi ini berfungsi dengan baik - diuji pada Windows 8.1. Saya memang memperhatikan bahwa ini case-sensitive.
oliver-clare
@ LordScree Ketika saya bekerja pada sistem case sensitivitas * un * x baik untuk saya! Saya bahkan mengatur sistem file untuk mengaktifkan nama file case sensitif. ;)
BenarY
Bekerja dengan baik bagi saya untuk - diuji di windows 7 X64
Mr Rubix
Ini tidak berfungsi jika aplikasi memiliki spasi dalam nama karena% x akhirnya menjadi bagian dari nama aplikasi hingga ruang pertama.
Chris
Solusi yang mungkin adalah memeriksa apakah aplikasi tidak ditemukan sebagai gantinya dengan memeriksa apakah% x == INFO: tapi saya tidak tahu versi Windows yang mana ini akan bekerja atau jika ada solusi yang lebih baik.
Chris
21

Saran npocmaka untuk menggunakan QPROCESS sebagai ganti TASKLIST bagus tetapi, jawabannya sangat besar dan kompleks sehingga saya merasa berkewajiban untuk memposting versi yang disederhanakan yang, saya kira, akan menyelesaikan masalah sebagian besar pengguna yang tidak mahir:

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

Kode di atas diuji pada Windows 7, dengan pengguna dengan administrator yang kuat.

aldemarcalazans
sumber
Saya hanya menggunakan ide ini untuk menghentikan proses otomatis menembak dua kali dan itu berfungsi seperti pesona!
Davy C
Saya harus mengatakan bahwa tidak seperti perintah ini, solusi tasklist tidak hanya terlihat terlalu rumit untuk permintaan sederhana, tetapi mereka juga menjalankan satu atau dua detik dan menggunakan banyak cpu! Ini jauh lebih baik, juga berfungsi tanpa izin admin (Windows Server 2012).
Eugene Marin
Ini tampaknya menjadi solusi paling sederhana dan terbaik (setidaknya bagi saya) karena berfungsi apa adanya ketika aplikasi memiliki spasi dalam namanya. Saya ingin tahu apa keterbatasan solusi ini dan mengapa tidak memiliki lebih banyak suara.
Chris
20

Di Windows Anda dapat menggunakan Windows Management Instrumentasi (WMI) untuk memastikan bahwa tidak ada aplikasi dengan baris perintah yang ditentukan diluncurkan, misalnya:

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)

vtrz
sumber
Perhatikan bahwa WMIC memerlukan hak administratif; jika Anda tidak memilikinya, maka Only the administrator group members can use WMIC.EXE.diikuti olehReason:Win32 Error: Access is denied.
Jeroen Wiert Pluimers
saya pikir ini adalah solusi terbaik, karena wmic memberi Anda baris perintah lengkap diluncurkan dan informasi lainnya jutaan ...
Glavić
13
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
Riccardo La Marca
sumber
3
Ini benar-benar berfungsi dengan baik. Sederhana! Perlu diketahui itu sensitif huruf kecuali Anda menambahkan /i.
Jason
8

Saya menggunakan PV.exe dari http://www.teamcti.com/pview/prcview.htm diinstal dalam Program Files \ PV dengan file batch seperti ini:

@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

sumber
1
ini berfungsi untuk saya di windows 7. Baris ke-2 adalah direktori yang berisi program, bukan program itu sendiri.
Fabio Cionini
8

Jawaban TrueY tampaknya merupakan solusi yang paling elegan, namun, saya harus melakukan sesuatu karena saya tidak mengerti apa yang sebenarnya terjadi. Ijinkan saya menghapus beberapa hal untuk semoga menghemat waktu untuk orang berikutnya.

Jawaban TrueY yang dimodifikasi:

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

Bagaimanapun, saya harap itu membantu. Saya tahu kadang-kadang membaca batch / command-line bisa agak membingungkan kadang-kadang jika Anda seorang pemula, seperti saya.

kayleeFrye_onDeck
sumber
6

The jawaban yang diberikan oleh Matt Lacey bekerja untuk Windows XP. Namun, pada Windows Server 2003 baris

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

kembali

INFO: Tidak ada tugas yang berjalan yang cocok dengan kriteria yang ditentukan.

yang kemudian dibaca saat proses sedang berjalan.

Saya tidak memiliki tumpukan pengalaman skrip batch, jadi soulution saya adalah untuk kemudian mencari nama proses dalam search.logfile dan memompa hasilnya ke file lain dan mencari itu untuk output apa pun.

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

Saya harap ini membantu orang lain.

benmod
sumber
Ini berfungsi untuk Win 2008. +1 untuk Tidak ada tugas sedang berjalan yang cocok dengan kriteria yang ditentukan.
Mangesh Pimpalkar
5

Saya suka alat WMICdan TASKLISTtetapi mereka tidak tersedia di rumah / edisi dasar QPROCESSwindows. Cara lain adalah dengan menggunakan perintah yang tersedia di hampir setiap mesin windows (untuk orang-orang yang memiliki layanan terminal - saya pikir hanya memenangkan XP tanpa SP2, jadi praktis setiap mesin 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

QPROCESSperintah tidak begitu kuat karena TASKLISTdan terbatas dalam menampilkan hanya 12 simbol nama proses tetapi harus dipertimbangkan jika TASKLISTtidak tersedia.

Penggunaan yang lebih sederhana di mana ia menggunakan nama jika proses sebagai argumen ( .exeakhiran adalah wajib dalam kasus ini di mana Anda memberikan nama yang dapat dieksekusi):

@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

Perbedaan antara dua cara QPROCESSpenggunaan adalah bahwa QPROCESS *daftar keinginan semua proses sementara QPROCESS some.exehanya akan memfilter proses untuk pengguna saat ini.

Menggunakan WMIobjek melalui exe skrip host windows alih-alih WMICjuga merupakan pilihan. Ini harus dijalankan juga pada setiap mesin windows (tidak termasuk yang mana WSH dimatikan tetapi ini adalah kasus yang jarang terjadi). Berikut file bat yang berisi daftar semua proses melalui WMI kelas dan dapat digunakan sebagai pengganti QPROCESSskrip di atas (ini adalah jscript / bat hybrid dan harus disimpan sebagai .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 );
}

Dan modifikasi yang akan memeriksa apakah suatu proses sedang berjalan:

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

Dua opsi dapat digunakan pada mesin yang tidak memiliki TASKLIST.

Teknik utamanya adalah menggunakan MSHTA. Ini akan berjalan di setiap mesin windows dari XP dan di atasnya dan tidak tergantung pada pengaturan host skrip windows. panggilan MSHTAdapat sedikit mengurangi kinerja (sekali lagi harus disimpan sebagai kelelawar):

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

Saya tidak tahu bagaimana melakukannya dengan CMD bawaan tetapi jika Anda punya grep Anda dapat mencoba yang berikut ini:

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

Hanya menyebutkan, jika nama tugas Anda sangat panjang maka tidak akan muncul secara keseluruhan dalam tasklisthasilnya, jadi mungkin lebih aman (selain lokalisasi) untuk memeriksa yang sebaliknya.

Variasi jawaban ini :

:: 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
)
drzaus
sumber
0

Saya mengasumsikan windows di sini. Jadi, Anda harus menggunakan WMI untuk mendapatkan informasi itu. Lihat arsip The Scripting Guy untuk banyak contoh tentang cara menggunakan WMI dari sebuah skrip.

Bukan saya
sumber
0

Saya menggunakan skrip yang disediakan oleh Matt (2008-10-02). Satu-satunya hal yang saya punya masalah adalah tidak akan menghapus search.logfile. Saya berharap karena saya harus ke cdlokasi lain untuk memulai program saya. Saya cdakan kembali ke tempat file BAT dan search.logberada, tetapi masih tidak akan menghapus. Jadi saya menyelesaikannya dengan menghapus search.logfile lebih dulu daripada yang terakhir.

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
Nin
sumber
1
@ Sebastian: Ada sedikit informasi tambahan yang ditambahkan di sini, jadi saya cenderung membiarkannya sebagai jawaban.
Bill the Lizard
0

Anda harus memeriksa nama proses induk, lihat artikel Proyek Kode tentang solusi berbasis NET ** .

Cara non-terprogram untuk memeriksa:

  1. Luncurkan Cmd.exe
  2. Luncurkan aplikasi (misalnya, c:\windows\notepad.exe)
  3. Periksa properti proses Notepad.exe di Process Explorer
  4. Periksa proses induk (Ini menunjukkan cmd.exe)

Hal yang sama dapat diperiksa dengan mendapatkan nama proses induk.

prakash
sumber
0

Membangun jawaban vtrz dan jawaban Samuel Renkert pada topik lain , saya datang dengan skrip berikut yang hanya berjalan %EXEC_CMD%jika belum berjalan:

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

Seperti yang dikatakan sebelumnya, ini memerlukan hak administratif.

Calimo
sumber
tidak berfungsi untuk saya, dan saya menggunakan akun admin. Sebuah kotak DOS muncul denganNode - (computer name) ERROR: Description = Invalid query
khaverim
1
Bekerja dengan baik untuk saya.
Mark Duncan
1
Berfungsi bagus untuk Windows 7 di sini. Tidak ada masalah.
galacticninja
0

Saya membutuhkan solusi dengan coba lagi. Kode ini akan berjalan sampai proses ditemukan dan kemudian membunuhnya. Anda dapat mengatur batas waktu atau apa pun jika Anda mau.

Catatan:

  • ".Exe" wajib diisi
  • Anda dapat membuat file dapat dijalankan dengan parameter, versi di bawah ini
    :: 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
        )

Jalankan dengan .\taskkill.bat ProgramToKill.exe

Patrick
sumber
-2

Saya biasanya menjalankan perintah berikut dalam cmd prompt untuk memeriksa apakah program.exe saya berjalan atau tidak:

tasklist | grep program
Rajeev Jayaswal
sumber