How to check if a process is running via a batch script

后端 未结 18 2086
一个人的身影
一个人的身影 2020-11-22 07:38

How can I check if an application is running from a batch (well cmd) file?

I need to not launch another instance if a program is already running. (I can\'t change th

相关标签:
18条回答
  • 2020-11-22 07:49

    I like Chaosmaster's solution! But I looked for a solution which does not start another external program (like find.exe or findstr.exe). So I added the idea from Matt Lacey's solution, which creates an also avoidable temp file. At the end I could find a fairly simple solution, so I share it...

    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
    

    This is working for me nicely...

    0 讨论(0)
  • 2020-11-22 07:52

    Building on vtrz's answer and Samuel Renkert's answer on an other topic, I came up with the following script that only runs %EXEC_CMD% if it isn't already running:

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

    As was said before, this requires administrative privileges.

    0 讨论(0)
  • 2020-11-22 07:53

    I used the script provided by Matt (2008-10-02). The only thing I had trouble with was that it wouldn't delete the search.log file. I expect because I had to cd to another location to start my program. I cd'd back to where the BAT file and search.log are, but it still wouldn't delete. So I resolved that by deleting the search.log file first instead of last.

    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 讨论(0)
  • 2020-11-22 07:54

    I like the WMIC and TASKLIST tools but they are not available in home/basic editions of windows.Another way is to use QPROCESS command available on almost every windows machine (for the ones that have terminal services - I think only win XP without SP2 , so practialy every windows machine):

    @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 command is not so powerful as TASKLIST and is limited in showing only 12 symbols of process name but should be taken into consideration if TASKLIST is not available.

    More simple usage where it uses the name if the process as an argument (the .exe suffix is mandatory in this case where you pass the executable name):

    @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
    

    The difference between two ways of QPROCESS usage is that the QPROCESS * will list all processes while QPROCESS some.exe will filter only the processes for the current user.

    Using WMI objects through windows script host exe instead of WMIC is also an option.It should on run also on every windows machine (excluding the ones where the WSH is turned off but this is a rare case).Here bat file that lists all processes through WMI classes and can be used instead of QPROCESS in the script above (it is a jscript/bat hybrid and should be saved as .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 );
    }
    

    And a modification that will check if a process is running:

    @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 two options could be used on machines that have no TASKLIST.

    The ultimate technique is using MSHTA . This will run on every windows machine from XP and above and does not depend on windows script host settings. the call of MSHTA could reduce a little bit the performance though (again should be saved as 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();
    
    0 讨论(0)
  • 2020-11-22 07:55

    I needed a solution with a retry. This code will run until the process is found and then kill it. You can set a timeout or anything if you like.

    Notes:

    • The ".exe" is mandatory
    • You could make a file runnable with parameters, version below
        :: 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
            )
    

    Run with .\taskkill.bat ProgramToKill.exe

    0 讨论(0)
  • 2020-11-22 07:56

    I usually execute following command in cmd prompt to check if my program.exe is running or not:

    tasklist | grep program
    
    0 讨论(0)
提交回复
热议问题