我有以下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 是一个发明的,不应该找到它,所以应该打印“找不到进程1”< / strong>,但它没有,它总是打印0。
但我注意到的是,如果我从dos提示符运行tasklist | findstr /i qwerty
,就在%errorlevel%
= 1之后。
可能或更好的答案是什么?
答案 0 :(得分:28)
添加
setlocal EnableDelayedExpansion
到脚本的开头,然后使用
!errorlevel!
代替%errorlevel%
延迟扩展将导致变量在执行时扩展 时间而不是解析时间
另一个问题的答案指出了我正确的方向:https://stackoverflow.com/a/6658935/10245
答案 1 :(得分:25)
如果返回码等于或高于指定的errorlevel,则ERRORLEVEL返回TRUE。在您的示例中,由于0小于1,因此如果实际错误代码为0或更高,则第一个errorlevel语句将始终为true。你想要的是首先测试errorlevel 1。
E.g:
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!
)
答案 2 :(得分:0)
您可以使用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