2010-10-15 21 views
19

tengo el siguiente código de lote ventanas:Errorlevel en un bucle For (ventanas batch)

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

Pero no funciona como espero.

Todo el nombre procesa iidbms, IIGCC, iigcd, dmfacp, dmfrcp, rmcmd son reales, y que se encuentran, en lugar QWERTY es un inventaron uno y no debe encuéntrelo, entonces debe imprimir "no se encontró proceso 1", pero no lo hace, siempre imprime 0.

Pero lo que he notado es que si ejecuto el tasklist | findstr /i qwerty desde el indicador de dos, justo después de que exista el %errorlevel% = 1.

¿Qué tipo de respuesta podría ser o mejor?

Respuesta

21

IF ERRORLEVEL devuelve TRUE si el código de retorno es igual o mayor que el nivel de error especificado. En su ejemplo, dado que 0 es menor que 1, la primera declaración de nivel de error siempre será verdadera si el código de error real es 0 o superior. Lo que quiere es probar primero el nivel de error 1.

ej .:

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 
) 

Otra cuestión es si quiere hacerse eco del nivel de error real desde dentro del bucle. Dado que las variables se resuelven antes del inicio del bucle, repitiendo% errorlevel% siempre lo hará eco de 0. Si desea eco del valor en el tiempo de ejecución, es necesario modificar el fragmento de este modo:

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

He invertido el orden (primero 1 y luego 0), pero la resultado es el mismo – aemme

+0

Si no ha cambiado el código publicado, necesita un goto después de su nivel de error 1 para omitir el siguiente enunciado, o cambiar su condición (usar NEQ, etc.). – JRL

+0

algún ejemplo ...? – aemme

0

Puede utilizar 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 

Uso:

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 
23

Añadir

setlocal EnableDelayedExpansion 

al inicio de la secuencia de comandos, a continuación, utilizar !errorlevel! en lugar de %errorlevel%

expansión retardada hará que las variables que ser ampliado en execu ción tiempo en lugar de en tiempo de análisis

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

La respuesta a otra pregunta que me señaló en la dirección correcta: https://stackoverflow.com/a/6658935/10245