views:

60

answers:

2

I have the following windows batch code:

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%)

)

But it doesn't work as I expect.

All the name processes iidbms, iigcc, iigcd, dmfacp, dmfrcp, rmcmd are real, and they are found, instead qwerty is an invented one and should not find it, so should print " no process found 1", but it doesn't, it always print 0.

But what I have noted is that if I run the "tasklist | findstr /i qwerty" from the dos prompt, just after there is the %errorlevel%=1.

What sort of answer could be or better is?

A: 

You can use 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

Usage:

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
ghostdog74
+1  A: 

IF ERRORLEVEL returns TRUE if the return code was equal to or higher than the specified errorlevel. In your example, since 0 is lower than 1, the first errorlevel statement will always be true if the actual error code is 0 or above. What you want is to test for errorlevel 1 first.

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
)

Another issue is if you want to echo the actual errorlevel from within the for loop. Since variables are resolved before the start of the loop, echoing %errorlevel% will always echo 0. If you want to echo the value at the execution time, you need to modify the snippet like so:

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!
)
JRL
I have inverted the order (first 1 then 0) but the resul is the same
aemme
If you haven't changed the posted code, then you need a goto after your errorlevel 1 to skip the next statement, or change your condition (use NEQ, etc.).
JRL
some example...?
aemme
I really think it is right hat you wrote. But I don't understand why in another part of the code the lines: unloaddb.exe -c test > abc.txt, if %errorlevel% equ 0 call :backup, if %errorlevel% equ call :no_backup, works fine....
aemme
I tested you second example and works perfectly. Do you know why in the comment I added just above (:backup, :no_backup) works?
aemme
@aemme: you would have to post the code.
JRL
the code is: unloaddb.exe -c test > abc.txt; if %errorlevel% equ 0 call :backup; if %errorlevel% equ 1 call :no_backup; or maybe you prefere i write it by mean "answer you question"....?
aemme