如何检查应用程序是否从批处理(好cmd)文件运行?

如果程序已经在运行,我不需要启动另一个实例。(我不能改变应用程序,使它只有单一实例。)

此外,应用程序可以作为任何用户运行。


当前回答

我提出的另一种可能,不需要保存文件,灵感来自于使用grep:

tasklist /fi "ImageName eq MyApp.exe" /fo csv 2>NUL | find /I "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Program is running

/fi ""定义了一个应用程序的过滤器,在我们的例子中,它是*.exe名称 CSV定义了输出格式,CSV是必需的,因为默认情况下,如果可执行文件的名称太长,它可能会被截断,从而无法被稍后的find匹配。 find /I表示不区分大小写的匹配,可以省略

有关整个语法,请参阅tasklist命令的手册页。

其他回答

我不知道如何用内置CMD这样做,但如果你有grep,你可以尝试以下:

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

你应该检查父进程名,参见代码项目中关于基于。net解决方案的文章**。

一种非编程的检查方法:

发射用于cmd . exe 启动一个应用程序(例如,c:\windows\notepad.exe) 在进程资源管理器中检查“Notepad.exe”进程的属性 检查父进程(显示cmd.exe)

同样可以通过获取父进程名进行检查。

我喜欢《混沌大师》的解决方案!但我寻找了一个解决方案,不启动另一个外部程序(如find.exe或findstr.exe)。所以我添加了Matt Lacey解决方案中的想法,它创建了一个同样可以避免的临时文件。最后我找到了一个相当简单的解决方案,所以我把它分享给大家……

SETLOCAL EnableExtensions
set EXE=MyProg.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF NOT %%x == %EXE% (
  echo %EXE% is Not Running
)

这对我很有用……

以上是编辑。最初的代码中显然有一个GOTO,有人在评论中认为这很粗俗。

空间

如果你担心程序名中可能有空格,那么你需要稍微复杂化代码:

SETLOCAL EnableExtensions
set EXE=My Prog.exe
FOR /F %%x IN ("%EXE%") do set EXE_=%%x
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF NOT %%x == %EXE_% (
  echo %EXE% is Not Running
)

无论其他正在运行的进程的名称中是否有空格,原始代码都可以正常工作。唯一需要关注的是我们所瞄准的进程是否有空间。

ELSE

请记住,如果您添加了ELSE子句,那么它将对已经运行的应用程序的每个实例执行一次。在运行此脚本时,不能保证只有一个实例在运行。

无论如何,如果你想要一个,一个GOTO或标志变量被指明。

理想情况下,目标应用程序应该已经互斥自己以防止多个实例,但这是另一个SO问题的主题,不一定适用于本问题的主题。

再次转到

我同意“ELSE”的评论。GOTO-less解决方案的问题是,可能会多次运行条件部分(和ELSE部分),所以它有点混乱,因为它必须退出循环。(对不起,我在这里不处理空间问题,因为它似乎相当罕见,并显示了一个解决方案)

SETLOCAL EnableExtensions
SET EXE=MyProg.exe
REM for testing
REM SET EXE=svchost.exe
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF NOT %%x == %EXE% (
  ECHO %EXE% is Not Running
  REM This GOTO may be not necessary
  GOTO notRunning
) ELSE (
  ECHO %EXE is running
  GOTO Running
)
...
:Running
REM If Running label not exists, it will loop over all found tasks

在Windows下,您可以使用Windows管理规范(WMI)来确保没有带有指定命令行的应用程序被启动,例如:

Wmic进程where (name="nmake.exe") get commandline | findstr /i /c:"/f load. exe"Mak“/c:”/f build。编译已经开始了!> %ALREADY_STARTED & exit /b 1)

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

@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