アプリケーションがバッチ(well cmd)ファイルから実行されているかどうかを確認するにはどうすればよいですか?
プログラムが既に実行されている場合、別のインスタンスを起動する必要はありません。(アプリを変更して単一インスタンスのみにすることはできません。)
また、アプリケーションは任意のユーザーとして実行されている可能性があります。
アプリケーションがバッチ(well cmd)ファイルから実行されているかどうかを確認するにはどうすればよいですか?
プログラムが既に実行されている場合、別のインスタンスを起動する必要はありません。(アプリを変更して単一インスタンスのみにすることはできません。)
また、アプリケーションは任意のユーザーとして実行されている可能性があります。
回答:
私が思いついた別の可能性は、grepの使用に触発されたものです:
tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Program is running
追加のファイルを保存する必要がないので、この方法をお勧めします。
tasklist /FI "IMAGENAME eq winword.exe" 2>NUL | find /I /N "winword.exe">NUL
/ に変更しましたif %ERRORLEVEL%==1 goto wordnotrunning
(ifパーツの周りの引用を疑う
/?
画面では翻訳されていません。だから例えばIMAGENAME
ポーランド語版ではNAZWA_OBRAZU
です。
tasklist /FI "IMAGENAME eq myapp.exe" /NH | find /I /N "myapp.exe" >NUL
では、最初のNULは不要に見えるように変更する必要がありました。「2」の意味がわかりません。/NHはオプションです。
これが私がそれを解決した方法です:
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
上記がまだ実行されていない場合は、メモ帳が開きます。
編集:これはタスクリストから隠されたアプリケーションを見つけられないことに注意してください。これには、別のユーザーとして実行されているすべてのスケジュールされたタスクが含まれます。これらは自動的に非表示になるためです。
カオスマスターの解決策が好きです!しかし、別の外部プログラム(find.exeやfindstr.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
これはうまく機能しています...
TASKLISTの代わりにQPROCESSを使用するnpocmakaの提案は素晴らしいですが、その答えは非常に大きくて複雑なので、かなり簡略化したバージョンを投稿する義務があるように感じます。
QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"
上記のコードは、管理者権限を持つユーザーを使用してWindows 7でテストされました。
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)
Only the administrator group members can use WMIC.EXE.
続けてReason:Win32 Error: Access is denied.
次のようなバッチファイルを使用して、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
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!
とにかく、それが役に立てば幸いです。私のように、初心者の場合、バッチ/コマンドラインを読むと時々混乱することがあります。
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
これが他の誰かの役に立つことを願っています。
WMIC
とTASKLIST
ツールは好きですが、QPROCESS
Windowsのホーム/ベーシックエディションでは使用できません。別の方法は、ほぼすべての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();
ちょうど言及します、あなたのタスク名が本当に長い場合、それは全体に表示されません 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
)
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
親プロセス名を確認する必要があります。.NETベースのソリューションに関するコードプロジェクトの記事**を参照してください。
非プログラム的なチェック方法:
c:\windows\notepad.exe
)親プロセス名を取得することで同じことを確認できます。
上に構築さ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.
)
前述のとおり、これには管理者権限が必要です。
Node - (computer name) ERROR: Description = Invalid query
再試行を伴う解決策が必要でした。このコードは、プロセスが見つかるまで実行され、その後プロセスを強制終了します。タイムアウトなど、必要に応じて設定できます。
ノート:
:: 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
私は通常、cmdプロンプトで次のコマンドを実行して、program.exeが実行されているかどうかを確認します。
tasklist | grep program