次のWindowsバッチコードがあります。
for %%i in (iidbms iigcc iigcd dmfacp dmfrcp rmcmd qwerty) do (
tasklist | findstr /i %%i
echo %errorlevel%
if %errorlevel% == 0 (echo %%i ok process found %errorlevel%)
if %errorlevel% == 1 (echo %%i no process found %errorlevel%)
)
しかし、期待どおりに機能しません。
すべての名前プロセスiidbms、iigcc、iigcd、dmfacp、dmfrcp、rmcmdは実数であり、代わりにqwertyは発明されたものであり、それを見つけるべきではないので、"no process found 1"を印刷する必要がありますが、そうではなく、常に0を印刷します。
しかし、私が指摘したのは、tasklist | findstr /i qwerty
dosプロンプトから、その直後に%errorlevel%
= 1。
どのような答えが良いか、それより良いですか?
IF ERRORLEVELは、戻りコードが指定されたエラーレベル以上の場合にTRUEを返します。あなたの例では、0は1よりも小さいため、実際のエラーコードが0以上の場合、最初のerrorlevelステートメントは常にtrueになります。まず、エラーレベル1をテストします。
例えば。:
for %%i in (iidbms iigcc iigcd dmfacp dmfrcp rmcmd qwerty) do (
tasklist | findstr /i %%i
if errorlevel 0 if not errorlevel 1 echo process
if errorlevel 1 if not errorlevel 2 echo process not found
)
別の問題は、forループ内から実際のエラーレベルをエコーしたい場合です。変数はループの開始前に解決されるため、%errorlevel%をエコーすると常に0がエコーされます。実行時に値をエコーしたい場合は、次のようにスニペットを変更する必要があります。
setlocal enabledelayedexpansion
for %%i in (iidbms iigcc iigcd dmfacp dmfrcp rmcmd qwerty) do (
tasklist | findstr /i %%i
if errorlevel 0 if not errorlevel 1 echo %%i ok process found !errorlevel!
if errorlevel 1 if not errorlevel 2 echo %%i no process found !errorlevel!
)
追加
setlocal EnableDelayedExpansion
スクリプトの先頭に、次に!errorlevel!
の代わりに %errorlevel%
遅延展開により、変数は解析時ではなく実行時に展開されます
私を正しい方向に向けた別の質問への答え: https://stackoverflow.com/a/6658935/10245
あなたはvbscriptを使うことができます、
NumArgs = WScript.Arguments.Count
strComputer="."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess in colProcessList
For i=0 To NumArgs-1
If InStr( objProcess.Name ,WScript.Arguments(i) ) > 0 Then
WScript.Echo "found:" & WScript.Arguments(i)
End If
Next
Next
使用法:
C:\test>cscript //nologo test.vbs Explorer spool svchost
found:svchost
found:svchost
found:svchost
found:svchost
found:svchost
found:Explorer
found:svchost
found:spool