2008-10-02 173 views
212

如何检查应用程序是否从批处理(well cmd)文件运行?如何通过批处理脚本检查进程是否正在运行

如果程序已经运行,我需要不启动另一个实例。 (我无法更改应用程序使其仅适用于单一实例。)

此外,应用程序可能以任何用户身份运行。

+0

[批处理程序以检查进程是否存在](http:// stackoverflow。com/questions/15449034/batch-program-to-check-if-process-exists) – 2016-11-29 08:27:42

+9

五年后问的问题重复吗? – 2016-12-06 21:34:59

+0

@LưuVĩnhPhúc他们甚至不是比较接近。 – 2017-04-01 18:00:51

回答

0

您应该检查父进程名称,请参阅The Code Project关于.NET based solution**的文章。

甲非程序的检查方法:

  1. 启动cmd.exe
  2. 启动的应用程序(例如,c:\windows\notepad.exe
  3. Notepad.exe进程的检查性质Process Explorer
  4. 检查父进程(显示cmd.exe)

同样可以检查通过获取父进程名称来编辑。

0

我假设窗口在这里。所以,你需要使用WMI来获取这些信息。查看脚本专家的archives了解如何从脚本使用WMI的大量示例。

+0

是窗口。如果pos我想在DOS中执行,而不是VBScript。 – 2008-10-02 13:39:12

56

以下是我已经工作了:

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 

以上将打开Notepad如果它尚未运行。

编辑:请注意,这不会找到任务列表中隐藏的应用程序。这将包括以不同用户身份运行的所有计划任务,因为这些会自动隐藏。

+1

这适用于我,在XP上。没有检查过其他东西。 – 2008-10-02 13:53:02

+2

将任务列表格式更改为CSV或任何其他格式都很重要,因为它的任务列表默认布局(表格)会截断打破逻辑的长影像名称。 – 2011-06-22 14:56:19

2

我不知道怎么做,内置在CMD但如果你有grep,你可以尝试以下方法:

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

我用PV.exe从安装在Program Files文件\ PV与http://www.teamcti.com/pview/prcview.htm批处理文件是这样的:

@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 
270

我想出了另一种可能性,通过使用grep的启发,就是:

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

它不需要保存额外的文件,所以我更喜欢这种方法。

0

我使用了script provided by Matt(2008-10-02)。我唯一遇到的问题是它不会删除search.log文件。我期望因为我不得不cd到另一个位置开始我的程序。我回到了BAT文件和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 
20

在Windows下你可以使用Windows Management Instrumentation(WMI),以确保与指定的命令行中没有应用程序被启动,例如:

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)

6

answer provided by Matt Lacey适用于Windows XP。但是,在Windows Server 2003中的线

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

回报

INFO: No tasks are running which match the specified criteria.

为正在运行的进程,然后读取。

我没有批处理脚本的经验,因此我的解决方案是在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 

我希望这可以帮助别人。

-1

大厦vtrz's answerSamuel Renkert's answer on an other topic,我想出了下面的脚本,只运行%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. 
) 

正如前面所说的,这需要管理权限。

3

我喜欢WMICTASKLIST工具,但它们不是在家里可用/的windows.Another方式的基本版本是使用提供QPROCESS命令几乎每一个Windows机器上(对于有终端服务的 - 我想只有获胜XP不带SP2,所以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也是一个选项。它也应该在每台Windows机器上运行(不包括WSH关闭的情况,但这种情况很少见)。在此bat文件,列出通过WMI类的所有进程,并可以在上面(这是一个JScript/BAT混合,并应保存为.bat)脚本用来代替QPROCESS

@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通话可以减少一点点的性能虽然(再次应保存为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(); 
31

我喜欢Chaosmaster的解决方案!但我寻找的解决方案不能启动另一个外部程序(如find.exefindstr.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 

这是为我工作很好...

7

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! 

无论如何,我希望帮助。我知道有时阅读批处理/命令行有时会让人困惑,如果你像我一样是新手。

0

另一种解决方案是:

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 
CD "Path that contains the program" 
TASKLIST | FINDSTR ProgramName > NUL 2> NUL 
IF %ERRORLEVEL%==1 (
START ProgramName.exe 
) 
endlocal 

使用“SETLOCAL”命令的建议,以改善与其他操作系统的兼容性。

即检查是否有过程正在运行的行是:

TASKLIST | FINDSTR ProgramName 

如果程序被关闭然后将在0

0

设置的“ERRORLEVEL”变量设置为1,否则我通常执行在命令提示符下面的命令来检查我的Program.exe运行与否:

tasklist | grep program 
6

npocmaka的建议,而不是使用TASKLIST QProcess中是伟大的,但是,它的答案是那么大,补偿法,我觉得有义务发布它的一个相当简化的版本,它,我想,可以解决大部分的非高级用户的问题:

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

上面的代码是在Windows 7测试,与管理员的用户 - 瑞。

相关问题