ファイル名にスペースがある実行中のプロセスを検出する

ファイル名にスペースがある実行中のプロセスを検出する

バッチ ファイルを使用して Windows 7 で実行中のプロセスを検出しようとしています。スペースのないプロセスは問題なく動作します (例: notepad.exe)。なぜ動作しないのか理解できず、助けていただけると幸いです。

コード

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set "EXE=My Process.exe"

FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto ProcessFound 

goto ProcessNotFound

:ProcessFound
echo 1
goto END

:ProcessNotFound
echo 0
goto END

:END

期待される結果

C:\test.bat
1

実結果

C:\test.bat
'Process.exe' is not recognized as an internal or external command,
operable program or batch file.
0

答え1

コードには大きな問題が 1 つありますが、これはプロセス名内のスペースとは関係ありません。

各行を実行すると、tasklist /NHプロセス名以外の情報が返されます。

C:\temp>tasklist /nh

System Idle Process              0 Services                   0         24 K
System                           4 Services                   0      2,200 K
smss.exe                       400 Services                   0      1,232 K

つまり、次のような行を取得しようとしています。

System Idle Process 0 Services 0 24 K(保持されるもの)、それが指定されたプロセス名 (つまり、 )%%xと等しいかどうかを確認します。System Idle Process

各行に提供される追加情報により、それらは決して等しくなることはないので、リストを取得する(またはさらに抽出する)方法を見つける必要があります。のみプロセス名。

また:

set "EXE=My Process.exe"引用符は必要ありません。等号の後の行にあるすべてが、左側に指定された変数に割り当てる値であることがわかります。したがって、set EXE=My Process.exeスペースがあっても問題なく動作します。

文字列を区切る通常の方法は、値部分を引用符で囲むことです (コメントで提案されているように)。ただし、Set は型ベースではないため (文字列と数値、三角形などを区別できません)、引用符も含められます。つまり、set Filename="My Name"Filename の値は"My Name"引用符を含めて になります。これを後で使用しようとすると (他のコマンドの他の引用符の間など)、混乱を招いたり、問題が発生したりする可能性があります。

答え2

目的を果たす別のコードをいくつか見つけました:

@echo off
tasklist /nh /fi "imagename eq My Process.exe" | find /i "My Process.exe" >nul && (
echo 1
) || (
echo 0
)

答え3

私はこれに偶然出くわしましたが、その答えは私のケースには役立ちませんでした。そこで、同様のケースに遭遇した人のために回避策を見つけました。

私の前の回答で述べられているように、set "EXE=My Process.exe"引用符なしでも問題なく動作します。

より大きな問題は for ループにあります。あなたがしたように実行すると、FOR /F %%x%%x にはプロセスの最初の単語のみが含まれていることに気付きます (この例でMyMy Process.exe)。

これを修正するには、FOR /F ループ コマンドでトークン フラグとデリミット フラグを使用します。最初の 2 つの文字列をトークンとして追加すると、2 つの変数とが得られMyProcess.exeそれらを組み合わせて元の変数と比較しますEXE

次のようになります:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set EXE=My Process.exe

FOR /F "tokens=1,2 delims= " %%G IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF "%%G %%H" == "%EXE%" goto ProcessFound 

goto ProcessNotFound

:ProcessFound
echo 1
goto END

:ProcessNotFound
echo 0
goto END

:END

関連情報