如何从批处理(cmd)文件中检查应用程序是否正在运行?
如果程序已在运行,我不需要启动另一个实例.(我无法更改应用程序以使其仅为单个实例.)
该应用程序也可以像任何用户一样运行.
我想出的另一种可能性是受到grep的启发,它是:
tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL if "%ERRORLEVEL%"=="0" echo Program is running
它不需要保存额外的文件,所以我更喜欢这种方法.
这是我如何解决的问题:
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
如果尚未运行,上面将打开记事本.
编辑:请注意,这不会找到任务列表中隐藏的应用程序.这将包括以不同用户身份运行的任何计划任务,因为这些任务会自动隐藏.
我喜欢Chaosmaster的解决方案!但我寻找的解决方案无法启动另一个外部程序(如find.exe或findstr.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
这很适合我......
在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)
npocmaka使用QPROCESS代替TASKLIST的建议很棒但是,它的答案是如此之大和复杂,以至于我觉得有必要发布一个非常简化的版本,我想这将解决大多数非高级用户的问题:
QPROCESS "myprocess.exe">NUL IF %ERRORLEVEL% EQU 0 ECHO "Process running"
上面的代码在Windows 7中进行了测试,用户具有管理员权限.
我使用安装在Program Files\PV中的http://www.teamcti.com/pview/prcview.htm中的PV.exe 和批处理文件,如下所示:
@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
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!
无论如何,我希望有所帮助.我知道有时读书批处理/命令行有时会让你感到困惑,如果你像我这样的新手.
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
Matt Lacey提供的答案适用于Windows XP.但是,在Windows Server 2003中
tasklist /FI "IMAGENAME eq notepad.exe" /FO CSV > search.log
回报
信息:没有正在运行的任务符合指定的条件.
然后在进程运行时读取.
我没有一堆批处理脚本的经验,所以我的搜索是在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
我希望这有助于其他人.
我喜欢WMIC
和TASKLIST
工具,但是它们在QPROCESS
Windows的家庭/基本版本中不可用。另一种方法是使用几乎每个Windows机器上都可用的命令(对于那些具有终端服务的机器-我认为只有Win XP才没有SP2,所以实际上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
该命令不那么强大,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列出了所有进程类,并且可以代替QPROCESS
上面的脚本使用(它是jscript / bat混合体,应另存为.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 ); }
修改将检查进程是否正在运行:
@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:" | 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();