アプリケーションがバッチ(well cmd)ファイルから実行されているかどうかを確認する方法を教えてください。
プログラムがすでに実行されている場合は、別のインスタンスを起動する必要はありません。 (私はそれが単一のインスタンスだけになるようにアプリを変更することはできません。)
また、アプリケーションは任意のユーザーとして実行されている可能性があります。
grep を使用したことに触発された、私が思いついたもう1つの可能性は:
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 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
まだ実行されていない場合、上記は メモ帳 を開きます。
編集:これはタスクリストから隠されたアプリケーションを見つけることはありません。これらのタスクは自動的に非表示になるため、これには別のユーザーとして実行されているスケジュール済みタスクも含まれます。
私はChaosmasterの解決策が好きです!しかし、私は 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
これはうまく私のために働いています...
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)
TASKLISTの代わりにQPROCESSを使用するというnpocmakaの提案は素晴らしいですが、その答えは非常に大きく複雑であるため、非常に単純化したバージョンを投稿することが義務付けられていると思います。
QPROCESS "myprocess.exe">NUL
IF %ERRORLEVEL% EQU 0 ECHO "Process running"
上記のコードはWindows 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!
とにかく、それが役立つことを願っています。私は時々あなたが私のような初心者のような人である場合時々バッチ/コマンドラインを読むことは一種の混乱の種になることができることを知っています。
私はのようなバッチファイルで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
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
私はこれが他の人に役立つことを願っています。
TASKLIST | FINDSTR ProgramName || START "" "Path\ProgramName.exe"
WMIC
およびTASKLIST
ツールは好きですが、home/basicエディションのWindowsでは使用できません。別の方法は、ほぼすべてのWindowsマシンで使用可能なQPROCESS
コマンドを使用することです(ターミナルサービスがあるマシンの場合-勝つだけだと思いますXPSP2なしで、実際にはすべての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
QPROCESS
を使用する2つの方法の違いは、QPROCESS *
がすべてのプロセスをリストするのに対し、QPROCESS some.exe
は現在のユーザーのプロセスのみをフィルタリングすることです。
また、WMI
の代わりにWindowsスクリプトHost exeを介してWMIC
オブジェクトを使用することもオプションです。これは、すべてのWindowsマシンでも実行する必要があります(WSHがオフになっているが、これはまれなケースです)。 WMIクラスを通じて、上記のスクリプトで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();
内蔵CMDでそのようにする方法はわかりませんが、 grep があれば、次のことを試すことができます。
tasklist /FI "IMAGENAME eq myApp.exe" | grep myApp.exe
if ERRORLEVEL 1 echo "myApp is not running"
ちなみに、あなたのタスク名が本当に長いのであれば、それが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
)
私はここで窓を想定しています。そのため、その情報を入手するにはWMIを使用する必要があります。スクリプトからWMIを使用する方法の例については、The Scripting Guyの アーカイブ をご覧ください。
私は 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ベースのソリューション** についての The Code Project の記事を参照してください。
プログラム的でないチェック方法
c:\windows\notepad.exe
)親プロセス名を取得しても同じことが確認できます。