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

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

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


当前回答

我使用了Matt提供的脚本。我唯一遇到的麻烦是它不能删除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

其他回答

TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"

以下是我的解决方法:

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

如果记事本没有运行,上面的操作将打开记事本。

编辑:注意这不会发现隐藏在任务列表中的应用程序。这将包括以不同用户运行的任何计划任务,因为这些任务将自动隐藏。

我使用了Matt提供的脚本。我唯一遇到的麻烦是它不能删除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

我喜欢《混沌大师》的解决方案!但我寻找了一个解决方案,不启动另一个外部程序(如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

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

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