2011-09-18 4 views
1

Mon objectif avec ce fichier batch est de trouver rapidement le nombre d'applications antivirus installées par un utilisateur. Je prévois de le faire en utilisant deux pour les boucles:DOS imbriqué pour les problèmes de boucle

  • boucle extérieure: itérer les noms de dossiers dans le répertoire Program Files
  • boucle intérieure: itérer une liste de noms antivirus communs (la variable AVList), recherche de correspondances avec le nom du répertoire actuel et ajout de chaque correspondance à la variable AntiVirus. Cela dit, voici mon code défaillant.

L'erreur que j'obtiens est "" était inattendu pour le moment.. Notez que j'ai actuellement des noms de dossiers dans mes fichiers de programme dans la variable AVList (à des fins de test).

::@echo off 
::variables 
set AntiVirus="Initial Value" 
set AVList=(adobe ccleaner auslogics) 

SETLOCAL EnableDelayedExpansion 

echo Checking Program Files... 

if "%Processor_Architecture%" == "AMD64" (
echo 64-bit OS 
echo. 
for /d %%f in ("%ProgramFiles(x86)%\*") do (
    echo "%%f" 
    SET "folder=%%f" 
    REM Begin loop to search substrings with words in AVList 
    Call:SearchAV "%folder%" 
    ) 
) 
else echo 32-bit OS 

echo. 
echo AntiVirus: %AntiVirus% 
echo. 

for /d %%g in ("%ProgramFiles%\*") do (
    echo "%%g" 
    SET "folder=%%g" 
    REM Begin loop to search substrings with words in AVList 
    Call:SearchAV "%folder%" 
    ) 
) 

:SearchAV 
for %%v in ("%AVList%") do (
    echo "%%v" 
    SET "av=%%v" 
    if /I NOT "!~1:av=!"=="!~1!" set AntiVirus="%AntiVirus%%av%" 
) 
GOTO:EOF 

echo. 
echo. 
echo %AntiVirus% found 
echo. 
echo Script created by Matthew Ammann, revised by Andriy M from StackOverflow 

@pause 

Voici la sortie redirigés vers un fichier journal:

C:\AVFinder>set AntiVirus="Initial Value" 

C:\AVFinder>set AVList=(adobe ccleaner auslogics) 

C:\AVFinder>SETLOCAL EnableDelayedExpansion 

C:\AVFinder>echo Checking Program Files... 
Checking Program Files... 

C:\AVFinder>if "AMD64" == "AMD64" (
echo 64-bit OS 
echo. 
for/%f in ("C:\Program Files (x86)\*") do (
echo "%f" 
SET "folder=%f" 
REM Begin loop to search substrings with words in AVList 
Call:SearchAV "C:\Program Files (x86)\Adobe" 
) 
) 
64-bit OS 


C:\AVFinder>(
echo "C:\Program Files (x86)\Adobe" 
SET "folder=C:\Program Files (x86)\Adobe" 
REM Begin loop to search substrings with words in AVList 
Call:SearchAV "C:\Program Files (x86)\Adobe" 
) 
"C:\Program Files (x86)\Adobe" 
"" was unexpected at this time. 

C:\AVFinder> if /I NOT "!~1:av=!"=="!~1!" set AntiVirus=""Initial Value""(adobe ccleaner auslogics)"" 

Où vais-je tort?

MISE À JOUR: J'ai finalement trouvé le temps de résoudre ce problème. Voici le code mis à jour:

::This script is licensed under the Creative Commons Attribution license (CC BY 3.0) 
::Simply mention the original author in the source code if you make a derivative work. 

@echo off 
::variables 
set AntiVirus= 
set AVList=(norton mcafee kaspersky symantec avg comodo avast avira webroot eTRUST) 

SETLOCAL EnableDelayedExpansion 

echo Checking Program Files... 

if "%Processor_Architecture%" == "AMD64" (
echo 64-bit OS 
echo. 
for /d %%f in ("%ProgramFiles(x86)%\*") do (
    echo "%%f" 
    SET "path=%%f" 
    Call:SearchAV "!path!" 
    ) 
) else echo 32-bit OS 

for /d %%g in ("%ProgramFiles%\*") do (
    echo "%%g" 
    SET "path=%%g" 
    Call:SearchAV "!path!" 
    ) 
) 
goto :END 

:SearchAV 
FOR %%a in %AVLIST% do (
    set res="%~n1" 
    set res=!res:%%a=! 
    if NOT "%~n1" ==!res! (
     ECHO "%~n1" contains %%a 
     if [!AntiVirus!] == [] (
      set AntiVirus="%~n1" 
     ) else (
      set AntiVirus=!AntiVirus!, "%~n1" 
     ) 
    ) 
) 
goto :eof 

:END 
echo. 
echo. 
echo !AntiVirus! found 
echo. 
echo Script created by Matthew Ammann, revised by members of Stack Overflow 
echo 

@pause 

Répondre

5

Je vois plusieurs problèmes

1.-Le lieu que vous avez la routine :searchAV empêche le code final de l'exécution.Donc, déplacez la routine vers le bas du fichier BAT; et remplacez le PAUSE par un GOTO :EOF. Voir HELP CALL

2.- La définition d'une variable d'environnement dans une boucle nécessite extension différée pour une affectation correcte. Et l'expansion retardée a besoin de la notation !VAR! pour l'inspection. Par conséquent, remplacez %FOLDER% par !FOLDER!. Mais, vous n'en avez pas besoin de toute façon, car vous pouvez utiliser directement la variable de boucle, %%g dans votre cas. Voir HELP SET.

3.- La mise en boucle de tous les éléments d'une liste de chaînes ne fonctionne pas avec la commande FOR avec la syntaxe utilisée. Voir HELP FOR.

Alors, jetez un oeil à cet extrait des idées sur la façon de corriger votre fichier BAT ...

@ECHO off 
SETLOCAL enabledelayedexpansion 
set AVLIST=(Windows Microsoft) 
FOR /d %%a in ("%ProgramFiles%\*") do (
    CALL :searchAV "%%a" 
    ) 
GOTO :eof 

:searchAV 
FOR %%a in %AVLIST% do (
    set res=%1 
    set res=!res:%%a=! 
    if NOT %1==!res! ECHO %1 contains %%a 
) 
GOTO :eof 
+0

Je sais que cela est d'environ un mois trop tard, mais je voulais faire un suivi. Merci pour l'aide, et j'ai posté le code final dans le message original! – KongMD

2

L'erreur "" was unexpected at this time. vient des guillemets dans set AntiVirus="%AntiVirus%%av%" dans votre sous-programme SearchAV. %av% est défini sur "%AVList%", c'est-à-dire: "(adobe ccleaner auslogics)", et parce que %AntiVirus% est vide au début, vous essayez de définir AntiVirus à ""(adobe ccleaner auslogics)"". SET ne semble pas aimer les citations vides ici, d'où le problème.

En outre, vous pouvez également prendre en compte les points suivants:

  • else echo 32-bit OS doit être sur la même ligne que son if correspondant.
  • premier et deuxième for boucles: %folder% doit être changé en !folder! pour bénéficier de l'expansion variable retardée.
  • :SearchAV sous-programme: la boucle for ne boucle pas sur les noms anti-virus (%%v séjours à "(adobe ccleaner auslogics)", !~1:av=! est toujours égale à av= et !~1! reste vide). Je voudrais plutôt utiliser un for /f pour tokenize la liste.
  • un goto doit être ajouté après la fin de la seconde pour que vous ne passiez plus dans le sous-programme.

Voici ma tentative il:

@echo off 
set AntiVirus= 
set AVList=Norton AntiVirus:ccleaner:auslogics 

SETLOCAL EnableDelayedExpansion 

echo Checking Program Files... 

if "%Processor_Architecture%" == "AMD64" (
echo 64-bit OS 
echo. 
    for /d %%f in ("%ProgramFiles(x86)%\*") do (
    echo %%f 
    SET folder=%%f 
    REM Begin loop to search substrings with words in AVList 
    call :SearchAV "!folder!" 
) 
) else echo 32-bit OS 

echo. 
echo AntiVirus (x86): %AntiVirus% 
echo. 

set AntiVirus= 
for /d %%g in ("%ProgramFiles%\*") do (
    echo %%g 
    SET folder=%%g 
    REM Begin loop to search substrings with words in AVList 
    Call:SearchAV "!folder!" 
    ) 
) 

echo. 
echo AntiVirus: %AntiVirus% 
goto :end 

:SearchAV 
set list=%AVList% 
:tokenize 
for /f "tokens=1* delims=:" %%v in ("!list!") do (
    SET av=%%v 
    SET list=%%w 
    if /I "!av!" == "%~n1" ( 
    if [!AntiVirus!] == [] (
     set AntiVirus=!av! 
    ) else (
     set AntiVirus=!AntiVirus!, !av! 
    ) 
) 
) 
if not [!list!] == [] goto :tokenize 
goto :eof 

:end 

Hope this helps.