プロセスがバッチスクリプトを介して実行されているかどうかを確認する方法


260

アプリケーションがバッチ(well cmd)ファイルから実行されているかどうかを確認するにはどうすればよいですか?

プログラムが既に実行されている場合、別のインスタンスを起動する必要はありません。(アプリを変更して単一インスタンスのみにすることはできません。)

また、アプリケーションは任意のユーザーとして実行されている可能性があります。



12
5年後に尋ねられた質問の複製?
Matt Lacey

@LưuVĩnhPhúc彼らは比較的近くさえいない。
枢機卿-モニカを2017年

関係ないと言った@JackKirby?
phuclv 2017

3
@oopsdazieええ、私はこの場合間違っているかもしれませんが、一般的なルールは、時間に関係なく、質問を最良の回答のコレクションで保持し、他の質問を複製として閉じることです
phuclv

回答:


330

私が思いついた別の可能性は、grepの使用に触発されたものです:

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

追加のファイルを保存する必要がないので、この方法をお勧めします。


7
これはうまく機能しました(windows XP SP3)。私見これはここで提案されている中で最もエレガントな方法であり、Windowsに同梱されているツールを使用するだけです
hello_earth

2
このコマンドラインの構文に問題がありました。私はそれを動作させるためにtasklist /FI "IMAGENAME eq winword.exe" 2>NUL | find /I /N "winword.exe">NUL/ に変更しましたif %ERRORLEVEL%==1 goto wordnotrunning(ifパーツの周りの引用を疑う
スティーブB

4
XPの他の言語バージョンでは、フィルター名はコードで翻訳されましたが、ヘルプ/?画面では翻訳されていません。だから例えばIMAGENAMEポーランド語版ではNAZWA_OBRAZUです。
rsk82 2012年

3
Win7 tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL では、最初のNULは不要に見えるように変更する必要がありました。「2」の意味がわかりません。/NHはオプションです。
Jan Doggen 2013年

12
tasklistは、一致するタスクを見つけるかどうかに関係なく、常にステータス0で終了します。そのため、それ自体では役に立たないのです。いずれにしても、find(またはfindstr)を使用して出力を確認する必要があるため、タスクリストのフィルターを使用しても意味がありません。タスクリストを実行するだけ| "myprog.exe"> nul:&& goto founditまたはsomesuchを見つけます。タスクリストに/ v(詳細)オプションが必要な場合があります。
デニス・ハウ

61

これが私がそれを解決した方法です:

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

上記がまだ実行されていない場合は、メモ帳が開きます。

編集:これはタスクリストから隠されたアプリケーションを見つけられないことに注意してください。これには、別のユーザーとして実行されているすべてのスケジュールされたタスクが含まれます。これらは自動的に非表示になるためです。


2
タスクリストのデフォルトのレイアウト(テーブル)は長いイメージ名を切り捨ててロジックを壊すため、タスクリストの形式をCSVまたはテーブル以外のものに変更することは重要です。
スコットホワイト

4
プロセスが見つからない場合でもTASKLISTが出力を生成するため、このソリューションはVistaでは機能しません。同じことがWindows 7にも当てはまると
思い

Windows 10では機能しません。search.logに「INFO:指定された基準に一致するタスクは実行されていません」が含まれています。そしてメモ帳が起動されていません
セルゲイ

46

カオスマスターの解決策が好きです!しかし、別の外部プログラム(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

これはうまく機能しています...


このソリューションはうまく機能します-Windows 8.1でテストされています。大文字と小文字が区別されることに気づきました。
oliver-clare 14

@LordScree un * xシステムで作業しているので、大文字と小文字の区別が適しています。大文字と小文字を区別するファイル名を有効にするようにファイルシステムを設定しました。;)
TrueY

私にとってはうまく機能
-Windows

%xが最初のスペースまでのアプリケーション名の一部になるため、アプリケーションの名前にスペースがある場合、これは機能しません。
クリス

可能な解決策は、代わりに%x == INFO:を確認してアプリケーションが見つからないかどうかを確認することですが、これが機能するWindowsのバージョンがわからない場合や、より良い解決策があるかどうかはわかりません。
クリス

21

TASKLISTの代わりにQPROCESSを使用するnpocmakaの提案は素晴らしいですが、その答えは非常に大きくて複雑なので、かなり簡略化したバージョンを投稿する義務があるように感じます。

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

上記のコードは、管理者権限を持つユーザーを使用してWindows 7でテストされました。


このアイデアを使用して、自動化されたプロセスの実行を2回停止するだけで、魅力的に機能しました。
Davy C

このコマンドとは異なり、タスクリストソリューションは、このような単純なクエリでは複雑すぎるように見えるだけでなく、1秒ほど実行され、大量のCPUを使用することにも注意してください。これははるかに優れており、管理者権限なしでも機能します(Windows Server 2012)。
Eugene Marin

これは、アプリケーションに名前にスペースが含まれている場合にそのまま機能するため、(少なくとも私にとっては)最も単純で最良の解決策のようです。このソリューションの制限と、それ以上の投票がない理由について知りたいです。
クリス

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)


WMICには管理者権限が必要です。お持ちでない場合は、Only the administrator group members can use WMIC.EXE.続けてReason:Win32 Error: Access is denied.
Jeroen Wiert Pluimers '14 / 02/14

私はWMICは...あなたに立ち上げた完全なコマンドラインとmilionその他の情報を与えるので、これは、最善の解決策だと思う
Glavić

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

3
これは実際にうまくいきます。シンプル!を追加しない限り、大文字と小文字が区別されることに注意してください/i
Jason

8

次のようなバッチファイルを使用して、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

1
これは私にとってWindows 7で機能します。2行目は、プログラム自体ではなく、プログラムを含むディレクトリです。
Fabio Cionini、2012

8

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!

とにかく、それが役に立てば幸いです。私のように、初心者の場合、バッチ/コマンドラインを読むと時々混乱することがあります。


6

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

これが他の誰かの役に立つことを願っています。


これはWin 2008で機能します。+ 1 for no tasks指定された基準に一致するタスクは実行されていません。
Mangesh Pimpalkar、2014

5

WMICTASKLISTツールは好きですが、QPROCESSWindowsのホーム/ベーシックエディションでは使用できません。別の方法は、ほぼすべてのWindowsマシンで利用できるコマンドを使用することです(ターミナルサービスを備えたものの場合-SP2なしでXPでのみ勝つと思うので、実際にはすべての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

2つのQPROCESS使用方法の違いは、QPROCESS *はすべてのプロセスを一覧表示QPROCESS some.exeし、現在のユーザーのプロセスのみをフィルタリングすることです。

WMI代わりにWindowsスクリプトホストexeを介してオブジェクトを使用することWMICもオプションです。すべての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 );
}

2つのオプションは、がないマシンで使用できます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();

2

組み込みのCMDでこれを行う方法はわかりませんが、 grepがある場合は、以下を試すことができます。

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

2

ちょうど言及します、あなたのタスク名が本当に長い場合、それは全体に表示されません 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
)

0

ここでは窓を想定しています。したがって、その情報を取得するにはWMIを使用する必要があります。スクリプトからWMIを使用する方法の多くの例については、Scripting Guyのアーカイブをご覧ください。


0

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

1
@セバスチャン:ここに追加の情報が少しあるので、答えとして残しておきたいと思います。
、トカゲ

0

親プロセス名を確認する必要があります。.NETベースのソリューションに関するコードプロジェクトの記事**を参照してください。

非プログラム的なチェック方法:

  1. Cmd.exeを起動します
  2. (例えば、アプリケーションを起動しますc:\windows\notepad.exe
  3. プロセスエクスプローラーで Notepad.exeプロセスのプロパティを確認する
  4. 親プロセスを確認します(cmd.exeが表示されます)

親プロセス名を取得することで同じことを確認できます。


0

上に構築さvtrzの答え他のトピックに関するサミュエル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.
)

前述のとおり、これには管理者権限が必要です。


私にとってはうまくいきませんでした、そして私は管理者アカウントを使用しています。DOSボックスが表示されますNode - (computer name) ERROR: Description = Invalid query
khaverim

1
私には問題なく動作します。
Mark Duncan

1
ここでWindows 7に最適です。問題ない。
galacticninja

0

再試行を伴う解決策が必要でした。このコードは、プロセスが見つかるまで実行され、その後プロセスを強制終了します。タイムアウトなど、必要に応じて設定できます。

ノート:

  • 「.exe」は必須です
  • 以下のバージョンのパラメータでファイルを実行可能にすることができます
    :: 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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.