我正在嘗試使用批次檔檢測 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
您的程式碼有一個主要問題,它與進程名稱中的空格無關。
當您運行時,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 僅包含進程的第一個單詞,在本例中My
來自My Process.exe
.
若要解決此問題,您可以在 FOR /F 循環命令中使用標記和分隔標誌。透過新增前 2 個字串作為標記,您將獲得 2 個變數My
和Process.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