如何检查应用程序是否正在从批处理文件(Cmd文件)运行?
如果程序已经在运行,则无需启动另一个实例。(我无法将应用更改为仅使其成为单个实例。)
该应用程序也可以任何用户身份运行。
如何检查应用程序是否正在从批处理文件(Cmd文件)运行?
如果程序已经在运行,则无需启动另一个实例。(我无法将应用更改为仅使其成为单个实例。)
该应用程序也可以任何用户身份运行。
Answers:
受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 winword.exe" 2>NUL | find /I /N "winword.exe">NUL
/ if %ERRORLEVEL%==1 goto wordnotrunning
以便使其起作用(怀疑if部件周围的引号
/?
屏幕中翻译的。因此,例如IMAGENAME
波兰语版本为NAZWA_OBRAZU
。
tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL
第一个NUL似乎是不必要的,我也不知道'2'是什么意思,/ NH是可选的。
这是我的解决方法:
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
这很适合我...
npocmaka建议使用QPROCESS而不是TASKLIST很好,但是它的答案是如此之大和复杂,以至于我不得不发布一个相当简化的版本,我想它将解决大多数非高级用户的问题:
QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"
上面的代码在Windows 7中经过测试,并具有管理员权限。
在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)
Only the administrator group members can use WMIC.EXE.
接下来Reason:Win32 Error: Access is denied.
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
/i
。
我使用安装在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!
无论如何,我希望能有所帮助。我知道有时阅读批处理/命令行有时会使您感到困惑,如果您像我一样是个新手。
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
可能会稍微降低性能(再次应保存为蝙蝠):
@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();
只需提及,如果您的任务名称确实很长,那么结果将不会完整显示tasklist
,因此检查相反的名称可能更安全(除了本地化)。
这个答案的变化:
:: 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
)
我使用了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
您应该检查父进程的名称,请参阅有关基于.NET的解决方案** 的代码项目文章。
一种非编程方式检查:
c:\windows\notepad.exe
)可以通过获取父进程名称来检查是否相同。
基于vtrz的答案和Samuel Renkert的另一个主题的答案,我想出了以下脚本,该脚本仅在%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.
)
如前所述,这需要管理权限。
Node - (computer name) ERROR: Description = Invalid query
我需要重试解决方案。该代码将一直运行,直到找到该进程,然后将其杀死。您可以设置超时,也可以根据需要设置任何内容。
笔记:
:: 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
)
与运行 .\taskkill.bat ProgramToKill.exe