我有以下的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是一个发明的,不应该find它,所以应该打印“no process found 1” ,但是它不,它总是打印0。
但是我注意到的是,如果我运行tasklist | findstr /i qwerty
从dos提示符中findtasklist | findstr /i qwerty
,就在%errorlevel%
= 1之后。
什么样的答案可能是更好的?
如果返回码等于或高于指定的错误级别,则IF ERRORLEVEL返回TRUE。 在你的例子中,因为0低于1,所以如果实际的错误代码是0或者大于0,那么第一个errorlevel语句总是为真。 你想要的是首先测试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 )
另一个问题是如果你想在echo循环中回显实际的错误级别。 由于变量在循环开始之前被解析,因此回显%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%
延迟扩展将导致变量在执行时而不是在解析时被扩展
〜http: //ss64.com/nt/delayedexpansion.html
另一个问题的答案,指出我在正确的方向: 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