Comment vérifier si un processus est en cours d'exécution via un script de traitement par lots

Comment puis-je vérifier si une application est en cours d'exécution à partir d'un fichier batch (well cmd)?

Je ne dois pas lancer une autre instance si un programme est déjà en cours d'exécution. (Je ne peux pas modifier l'application pour en faire une seule instance.)

aussi l'application pourrait être en cours d'exécution comme n'importe quel utilisateur.

222
demandé sur Keng 2008-10-02 17:35:00

17 réponses

une autre possibilité que j'ai trouvé, inspiré par l'utilisation de grep , est:

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

Il n'a pas besoin d'enregistrer un fichier supplémentaire, donc je préfère cette méthode.

282
répondu pkamb 2017-02-06 09:35:44

Voici comment j'ai compris:

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

ce qui précède ouvrira Bloc-notes s'il n'est pas déjà en cours d'exécution.

Edit: notez que cela ne trouvera pas d'applications cachées dans la liste des tâches. Cela inclut toutes les tâches programmées exécutées en tant qu'utilisateur différent, car elles sont automatiquement cachées.

58
répondu Matt Lacey 2012-03-05 18:36:21

j'aime la solution de Chaosmaster! Mais j'ai cherché une solution qui ne démarre pas un autre programme externe (comme find.exe ou findstr.exe ). J'ai donc ajouté l'idée de la solution de Matt Lacey, qui crée un fichier temp également évitable. À la fin j'ai pu trouver une solution plutôt simple, donc je la partage...

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

ça me va très bien...

34
répondu TrueY 2015-06-04 11:40:54

sous Windows, vous pouvez utiliser Windows Management Instrumentation (WMI) pour vous assurer qu'aucune application avec la ligne de commande spécifiée n'est lancée, par exemple:

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)

20
répondu vtrz 2011-01-24 14:23:19

la suggestion de npocmaka d'utiliser QPROCESS à la place de TASKLIST est grande mais, sa réponse est si grande et complexe que je me sens obligé de poster une version très simplifiée de celui-ci qui, je suppose, va résoudre le problème de la plupart des utilisateurs non avancés:

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

le code ci-dessus a été testé dans Windows 7, avec un utilisateur avec des rigths d'administrateur.

12
répondu aldemarcalazans 2017-05-11 17:57:43

J'utilise PV.exe de http://www.teamcti.com/pview/prcview.htm installé dans les fichiers de programme\PV avec un fichier par lot comme ceci:

@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
8
répondu 2008-12-02 18:29:57

la réponse de TrueY semblait la solution la plus élégante, cependant, j'ai dû faire quelques bêtises parce que je ne comprenais pas exactement ce qui se passait. Laissez-moi clarifier les choses pour, espérons, gagner du temps pour la prochaine personne.

TrueY modifiée de la Réponse:

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

de toute façon, j'espère que ça aidera. Je sais que parfois lire la ligne de commande peut être un peu déroutant parfois si vous êtes une sorte de débutant, comme moi.

8
répondu kayleeFrye_onDeck 2016-02-04 18:43:31

Le réponse fournie par Matt Lacey works pour Windows XP. Toutefois, dans Windows Server 2003 la ligne

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

retourne

INFO: aucune tâche correspondant aux critères spécifiés n'est exécutée.

qui est alors lu pendant que le processus est en cours.

Je n'ai pas un tas d'expérience de script par lot, donc ma soulution est de chercher le nom du processus dans le fichier search.log et pomper les résultats dans un autre fichier et rechercher que pour toute sortie.

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

j'espère que cela aide quelqu'un d'autre.

6
répondu benmod 2017-05-23 12:10:54

j'aime WMIC et TASKLIST outils, mais ils ne sont pas disponibles dans la maison de base, les éditions de windows.Une autre façon est d'utiliser la commande QPROCESS disponible sur presque toutes les machines windows (pour celles qui ont des services de terminal - je pense que seulement win XP sans SP2 , donc pratiquement toutes les machines 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 commande n'est pas aussi puissant que TASKLIST et est limité à l'affichage de seulement 12 symboles du nom du procédé, mais doit être pris en considération si TASKLIST n'est pas disponible.

usage plus simple où il utilise le nom si le processus comme argument (le suffixe .exe est obligatoire dans ce cas où vous passez le nom exécutable):

@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

la différence entre deux façons d'utiliser QPROCESS est que le QPROCESS * énumérera tous les processus tandis que QPROCESS some.exe filtrera seuls les processus pour l'utilisateur actuel.

utilisant WMI objets à travers Windows script host exe au lieu de WMIC est également une option.Il devrait également fonctionner sur toutes les machines windows (à l'exclusion de celles où le WSH est éteint, mais c'est un cas rare).Ici le fichier bat qui liste tous les processus à travers les classes WMI et peut être utilisé à la place de QPROCESS dans le script ci-dessus (c'est un hybride JScript/bat et devrait être enregistré comme .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 );
}

et une modification qui vérifiera si un processus est en cours d'exécution:

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

les deux options peuvent être utilisées sur les machines qui n'ont pas de TASKLIST .

la technique ultime est d'utiliser MSHTA . Cela s'exécute sur toutes les machines windows à partir de XP et au-dessus et ne dépend pas des paramètres de l'hôte du script windows. l'appel de MSHTA pourrait réduire un peu la performance cependant (encore une fois devrait être enregistré comme 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();
4
répondu npocmaka 2014-08-08 20:11:28
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
3
répondu Riccardo La Marca 2018-03-15 16:51:18

Je ne sais pas comment le faire avec construit dans CMD, mais si vous avez grep vous pouvez essayer ce qui suit:

tasklist /FI "IMAGENAME eq myApp.exe" | grep myApp.exe
if ERRORLEVEL 1 echo "myApp is not running"
2
répondu Motti 2008-10-02 13:57:59

il suffit de mentionner que, si votre nom de tâche est vraiment long, il n'apparaîtra pas dans son intégralité dans le résultat tasklist , de sorte qu'il pourrait être plus sûr (autre que la localisation) de vérifier le contraire.

Variation cette réponse :

:: 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
)
1
répondu drzaus 2018-05-11 19:38:18

je suppose qu'il y a des fenêtres ici. Donc, vous aurez besoin d'utiliser WMI pour obtenir cette information. Consultez le archives de Guy pour de nombreux exemples sur la façon d'utiliser WMI à partir d'un script.

0
répondu NotMe 2008-10-02 13:37:29

j'ai utilisé le script fourni par Matt (2008-10-02). La seule chose qui m'a posé problème, c'est qu'il ne supprimerait pas le fichier search.log . Je m'attends parce que j'ai dû cd à un autre endroit pour commencer mon programme. J' cd 'd retour à l'endroit où le fichier BAT et search.log , mais il ne le supprimez pas. J'ai donc résolu cela en supprimant le fichier search.log en premier au lieu de dernier.

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
0
répondu Nin 2017-05-23 11:33:24

vous devez vérifier le nom du processus parent, voir le projet de Code article à propos d'une solution basée sur .NET** .

Un non-programmatique moyen de vérifier:

  1. Lancement Cmd.exe
  2. lancer une application (par exemple, c:\windows\notepad.exe )
  3. vérifier les propriétés du bloc-notes.exe processus Process Explorer
  4. vérifier pour le processus parent (ceci montre cmd.exe) 1519110920"

la même chose peut être vérifiée en obtenant le nom du processus parent.

0
répondu prakash 2012-03-05 18:38:59

j'exécute habituellement la commande suivante dans cmd prompt pour vérifier si mon programme.exe est en cours d'exécution ou non:

tasklist | grep program
0
répondu Rajeev Jayaswal 2017-03-22 09:13:17

S'appuyant sur réponse de vtrz et réponse de Samuel Renkert sur un autre sujet , j'ai trouvé le script suivant qui ne tourne %EXEC_CMD% que s'il n'est pas déjà en cours d'exécution:

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

comme nous l'avons déjà dit, cela nécessite des privilèges administratifs.

-1
répondu Calimo 2017-05-23 12:03:09