我对此批处理文件的目标是快速了解用户安装了多少个防病毒应用程序。我计划通过使用两个for循环来实现这一点:
话虽如此,这是我失败的代码。我得到的错误是“”此时出乎意料。。请注意,我目前在AVList变量的Program Files中有文件夹名称(用于测试目的)。
::@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
这是重定向到日志文件的输出:
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)""
我哪里错了?
更新:我终于找到了一些时间来解决这个问题。这是更新后的代码:
::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
答案 0 :(得分:5)
我看到了几个问题
1.-您拥有:searchAV
例程的位置会阻止最终代码执行。因此,将例程移到BAT文件的底部;并将PAUSE
替换为GOTO :EOF
。见HELP CALL
2.-在循环中设置环境变量需要延迟扩展才能正确分配。延迟扩展需要!VAR!
符号进行检查。因此,请将%FOLDER%
更改为!FOLDER!
。但是,您无论如何都不需要它,因为您可以在您的情况下直接使用循环变量%%g
。见HELP SET
。
3.-循环使用字符串列表中的所有项目不能使用FOR
命令和您使用的语法。请参阅HELP FOR
。
因此,请查看此摘录,了解有关如何更正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
答案 1 :(得分:2)
"" was unexpected at this time.
错误来自set AntiVirus="%AntiVirus%%av%"
子例程中SearchAV
的引号。 %av%
设置为"%AVList%"
,即"(adobe ccleaner auslogics)"
,并且由于%AntiVirus%
在开头为空,您尝试将AntiVirus
设置为{{1} }}。 ""(adobe ccleaner auslogics)""
似乎不喜欢这里的空引号,因此存在问题。
除此之外,您可能还需要考虑以下几点:
SET
需要与其对应的else echo 32-bit OS
。if
循环:for
需要更改为%folder%
才能从延迟变量扩展中受益。!folder!
子例程::SearchAV
循环不会循环反病毒名称(for
停留在%%v
,"(adobe ccleaner auslogics)"
始终等于{{ 1}}和!~1:av=!
保持为空。我会使用av=
来标记列表。以下是我的尝试:
!~1!
希望这有帮助。