For循环中的错误级别(Windows批处理)

31

我有以下的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。

但我已经注意到,如果我在 DOS 提示符下运行 tasklist | findstr /i qwerty,紧接着就会发现 %errorlevel% = 1。

有什么样的答案可能会更好呢?

3个回答

42

33

IF ERRORLEVEL在返回代码等于或高于指定的错误级别时返回TRUE。在您的示例中,由于0小于1,如果实际错误代码为0或更高,则第一个errorlevel语句将始终为true。您想要测试的是先测试errorlevel 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!
)

-1

你可以使用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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接