如何从批处理(cmd)文件中检查应用程序是否正在运行?
如果程序已经运行,我不需要启动另一个实例。 (我无法更改应用程序以使其仅为单个实例。)
该应用程序也可以像任何用户一样运行。
答案 0 :(得分:298)
我提出的另一种可能性,灵感来自于使用grep,是:
tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Program is running
它不需要保存额外的文件,所以我更喜欢这种方法。
答案 1 :(得分:58)
以下是我如何解决这个问题:
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。
编辑:请注意,这不会找到任务列表中隐藏的应用程序。这将包括以不同用户身份运行的任何计划任务,因为这些任务会自动隐藏。
答案 2 :(得分:35)
我喜欢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
这对我很有帮助......
答案 3 :(得分: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)
答案 4 :(得分:17)
npocmaka使用QPROCESS代替TASKLIST的建议很棒但是,它的答案是如此之大和复杂,以至于我觉得有必要发布一个非常简化的版本,我想这将解决大多数非高级版本的问题用户:
QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"
上面的代码在Windows 7中进行了测试,用户具有管理员权限。
答案 5 :(得分:8)
我使用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
答案 6 :(得分:8)
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!
无论如何,我希望有所帮助。我知道,如果你像我这样的新手,阅读批处理/命令行有时会让人感到困惑。
答案 7 :(得分:6)
answer provided by 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
我希望这有助于其他人。
答案 8 :(得分:6)
values
答案 9 :(得分:5)
我喜欢WMIC
和TASKLIST
工具,但它们在家庭/基本版本的Windows中不可用。另一种方法是在几乎每台Windows机器上都使用QPROCESS
命令(用于那些有终端服务的人 - 我认为只有没有SP2才能赢得XP,所以每台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
将仅过滤当前用户的进程。
通过Windows脚本主机exe而不是WMI
使用WMIC
对象也是一个选项。它也应该在每台Windows机器上运行(不包括关闭WSH的那些但是这是一个罕见的情况)。这是通过WMI类列出所有进程的bat文件,可以在上面的脚本中使用而不是QPROCESS
(它是一个jscript / bat混合,应保存为.bat
):< / p>
@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
的调用可以减少一点性能(同样应该保存为蝙蝠):
@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();
答案 10 :(得分:2)
我不知道如何使用内置CMD,但如果你有grep,你可以尝试以下方法:
tasklist /FI "IMAGENAME eq myApp.exe" | grep myApp.exe
if ERRORLEVEL 1 echo "myApp is not running"
答案 11 :(得分:0)
我在这里假设窗户。因此,您需要使用WMI来获取该信息。查看脚本专家archives,了解有关如何从脚本中使用WMI的大量示例。
答案 12 :(得分:0)
如果您有多个同名的 .exe 文件并且您只想检查其中一个(例如您关心 C:\MyProject\bin\release\MyApplication.exe 而不是 C:\MyProject\ bin\debug\MyApplication.exe) 然后你可以使用以下内容:
@echo off
set "workdir=C:\MyProject\bin\release"
set "workdir=%workdir:\=\\%"
setlocal enableDelayedExpansion
for /f "usebackq tokens=* delims=" %%a in (`
wmic process where 'CommandLine like "%%!workdir!%%" and not CommandLine like "%%RuntimeBroker%%"' get CommandLine^,ProcessId /format:value
`) do (
for /f "tokens=* delims=" %%G in ("%%a") do (
if "%%G" neq "" (
rem echo %%G
set "%%G"
rem echo !ProcessId!
goto :TheApplicationIsRunning
)
)
)
echo The application is not running
exit /B
:TheApplicationIsRunning
echo The application is running
exit /B
答案 13 :(得分:0)
我需要重试解决方案。该代码将一直运行,直到找到该进程,然后将其杀死。您可以设置超时时间,也可以设置任何时间。
注意:
string
:: 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
)
答案 14 :(得分:0)
我使用script provided by Matt(2008-10-02)。我遇到的唯一问题是它不会删除search.log
文件。我希望因为我必须cd
到另一个位置来启动我的程序。我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
答案 15 :(得分:0)
您应该检查父进程名称,请参阅The Code Project有关.NET based solution**的文章。
检查的非程序化方式:
c:\windows\notepad.exe
)可以通过获取父进程名称来检查相同内容。
答案 16 :(得分:-1)
在vtrz's answer和Samuel 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.
)
如前所述,这需要管理权限。
答案 17 :(得分:-2)
我通常在cmd提示符下执行以下命令来检查我的program.exe是否正在运行:
tasklist | grep program