2008-10-02 207 views
212

如何檢查應用程序是否從批處理(well cmd)文件運行?如何通過批處理腳本檢查進程是否正在運行

如果程序已經運行,我需要不啓動另一個實例。 (我無法更改應用程序使其僅適用於單一實例。)

此外,應用程序可能以任何用戶身份運行。

+0

[批處理程序以檢查進程是否存在](http:// stackoverflow。com/questions/15449034/batch-program-to-check-if-process-exists) – 2016-11-29 08:27:42

+9

五年後問的問題重複嗎? – 2016-12-06 21:34:59

+0

@LưuVĩnhPhúc他們甚至不是比較接近。 – 2017-04-01 18:00:51

回答

0

您應該檢查父進程名稱,請參閱The Code Project關於.NET based solution**的文章。

甲非程序的檢查方法:

  1. 啓動cmd.exe
  2. 啓動的應用程序(例如,c:\windows\notepad.exe
  3. Notepad.exe進程的檢查性質Process Explorer
  4. 檢查父進程(顯示cmd.exe)

同樣可以檢查通過獲取父進程名稱來編輯。

0

我假設窗口在這裏。所以,你需要使用WMI來獲取這些信息。查看腳本專家的archives瞭解如何從腳本使用WMI的大量示例。

+0

是窗口。如果pos我想在DOS中執行,而不是VBScript。 – 2008-10-02 13:39:12

56

以下是我已經工作了:

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如果它尚未運行。

編輯:請注意,這不會找到任務列表中隱藏的應用程序。這將包括以不同用戶身份運行的所有計劃任務,因爲這些會自動隱藏。

+1

這適用於我,在XP上。沒有檢查過其他東西。 – 2008-10-02 13:53:02

+2

將任務列表格式更改爲CSV或任何其他格式都很重要,因爲它的任務列表默認佈局(表格)會截斷打破邏輯的長影像名稱。 – 2011-06-22 14:56:19

2

我不知道怎麼做,內置在CMD但如果你有grep,你可以嘗試以下方法:

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

我用PV.exe從安裝在Program Files文件\ PV與http://www.teamcti.com/pview/prcview.htm批處理文件是這樣的:

@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 
270

我想出了另一種可能性,通過使用grep的啓發,就是:

tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL 
if "%ERRORLEVEL%"=="0" echo Program is running 

它不需要保存額外的文件,所以我更喜歡這種方法。

0

我使用了script provided by Matt(2008-10-02)。我唯一遇到的問題是它不會刪除search.log文件。我期望因爲我不得不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 
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)

6

answer provided by Matt Lacey適用於Windows XP。但是,在Windows Server 2003中的線

tasklist /FI "IMAGENAME eq notepad.exe" /FO CSV > search.log 

回報

INFO: No tasks are running which match the specified criteria.

爲正在運行的進程,然後讀取。

我沒有批處理腳本的經驗,因此我的解決方案是在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 

我希望這可以幫助別人。

-1

大廈vtrz's answerSamuel 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. 
) 

正如前面所說的,這需要管理權限。

3

我喜歡WMICTASKLIST工具,但它們不是在家裏可用/的windows.Another方式的基本版本是使用提供QPROCESS命令幾乎每一個Windows機器上(對於有終端服務的 - 我想只有獲勝XP不帶SP2,所以practialy每個窗口機):

@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類的所有進程,並可以在上面(這是一個JScript/BAT混合,並應保存爲.bat)腳本用來代替QPROCESS

@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通話可以減少一點點的性能雖然(再次應保存爲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(); 
31

我喜歡Chaosmaster的解決方案!但我尋找的解決方案不能啓動另一個外部程序(如find.exefindstr.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 

這是爲我工作很好...

7

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! 

無論如何,我希望幫助。我知道有時閱讀批處理/命令行有時會讓人困惑,如果你像我一樣是新手。

0

另一種解決方案是:

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 
CD "Path that contains the program" 
TASKLIST | FINDSTR ProgramName > NUL 2> NUL 
IF %ERRORLEVEL%==1 (
START ProgramName.exe 
) 
endlocal 

使用「SETLOCAL」命令的建議,以改善與其他操作系統的兼容性。

即檢查是否有過程正在運行的行是:

TASKLIST | FINDSTR ProgramName 

如果程序被關閉然後將在0

0

設置的「ERRORLEVEL」變量設置爲1,否則我通常執行在命令提示符下面的命令來檢查我的Program.exe運行與否:

tasklist | grep program 
6

npocmaka的建議,而不是使用TASKLIST QProcess中是偉大的,但是,它的答案是那麼大,補償法,我覺得有義務發佈它的一個相當簡化的版本,它,我想,可以解決大部分的非高級用戶的問題:

QPROCESS "myprocess.exe">NUL 
IF %ERRORLEVEL% EQU 0 ECHO "Process running" 

上面的代碼是在Windows 7測試,與管理員的用戶 - 瑞。

相關問題