Question

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 prints 0.

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

What sort of answer could be or better is?

Was it helpful?

Solution

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

OTHER TIPS

Add

setlocal EnableDelayedExpansion

to the start of your script, then use !errorlevel! instead of %errorlevel%

Delayed Expansion will cause variables to be expanded at execution time rather than at parse time

~ http://ss64.com/nt/delayedexpansion.html

The answer to another question that pointed me in the right direction: https://stackoverflow.com/a/6658935/10245

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top