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

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

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


当前回答

我通常在cmd提示符下执行以下命令来检查我的program.exe是否正在运行:

tasklist | grep program

其他回答

在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)

我通常在cmd提示符下执行以下命令来检查我的program.exe是否正在运行:

tasklist | grep program

我喜欢WMIC和TASKLIST工具,但是在windows的家庭/基本版本中没有。另一种方法是在几乎所有windows机器上使用QPROCESS命令(对于那些有终端服务的机器-我认为只有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不可用,则应考虑使用QPROCESS命令。

更简单的用法,它使用进程名作为参数(在这种情况下,当你传递可执行名称时,.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而不是WMIC使用WMI对象也是一种选择。它还应该在每台windows机器上运行(不包括关闭WSH的机器,但这种情况很少见)。下面是一个通过WMI类列出所有进程的bat文件,可以用来代替上面脚本中的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。这将运行在每一台windows机器从XP和以上,不依赖于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:<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();

我使用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

马特·莱西(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

我希望这能帮助到其他人。