web-dev-qa-db-fra.com

Errorlevel dans une boucle For (fenêtres de traitement par lots)

J'ai le code de lot Windows suivant:

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

Mais cela ne fonctionne pas comme je l’attends.

Tous les processus de nom iidbms , iigcc , iigcd , dmfacp , dmfrcp , rmcmd sont réels, et ils sont trouvés, à la place qwerty est un inventé et ne devrait pas le trouver, donc il faudrait imprimer "aucun processus trouvé 1" , mais ce n’est pas, cela affiche toujours 0.

Mais ce que j’ai noté, c’est que si j’exécute le tasklist | findstr /i qwerty à partir de l’invite DOS, juste après, le %errorlevel% = 1.

Quel genre de réponse pourrait être ou mieux est?

21
user461487

IF ERRORLEVEL renvoie VRAI si le code de retour est égal ou supérieur au niveau d'erreur spécifié. Dans votre exemple, puisque 0 est inférieur à 1, la première instruction errorlevel sera toujours vraie si le code d'erreur réel est 0 ou supérieur. Ce que vous voulez, c'est d'abord tester le niveau d'erreur 1.

Par exemple.:

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
)

Un autre problème est de savoir si vous voulez faire écho au niveau d'erreur réel depuis la boucle for. Comme les variables sont résolues avant le début de la boucle, l'écho de% errorlevel% sera toujours égal à 0. Si vous souhaitez répercuter la valeur au moment de l'exécution, vous devez modifier le fragment de la manière suivante:

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

Ajouter 

setlocal EnableDelayedExpansion

au début de votre script, utilisez ensuite !errorlevel! au lieu de %errorlevel%

L’expansion retardée entraîne l’extension des variables au moment de l’exécution Plutôt qu’au moment de l’analyse

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

La réponse à une autre question qui m’allait dans la bonne direction: https://stackoverflow.com/a/6658935/10245

26
Tim Abell

Vous pouvez utiliser 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
0
ghostdog74