如何处理批处理脚本嵌套循环中的变量?

如何处理批处理脚本嵌套循环中的变量?

以下批次运行良好,直到出现注释“以下内容未按预期执行”我尝试了任何类型的 %; %%, ! 围绕变量但总是失败,要么没有任何东西,要么出现错误!

rem @ECHO OFF
ECHO %~dp0
ECHO %~dpnx0
SET fileNameForWMIC=
SET "7ZAEXE=7za.exe"
SET "SOURCE=C:\Program Files (x86)\my prog\PFM\*.*"
SET "LOCATION=C:\Program Files (x86)\my prog\PFM"
SET "TARGET=PFM.7z"
SET "REFFILE=NEWPFM.7z"
SET "IMPFILE=verPFM.txt"
setlocal enabledelayedexpansion
SET 7ZAEXE=%~dp0!7ZAEXE!
ECHO !7ZAEXE!
SET TARGET=%~dp0!TARGET!
ECHO !TARGET!
SET REFFILE=%~dp0!REFFILE!
ECHO !REFFILE!
SET IMPFILE=%~dp0!IMPFILE!
ECHO !IMPFILE!
rem "!7ZAEXE!" a "!TARGET!" @"!IMPFILE!" 
rem the whole directory
rem for /D %%X in ("!SOURCE!") do  !7ZAEXE! a "!TARGET!" "%%X"
rem only the important files listed in text file
FOR /F "usebackq skip=1 tokens=1,2 delims=," %%G IN ("%IMPFILE%") DO ( 
  echo %%G version %%H
  SET fileNameForWMIC=%%G 
  SET GoodVer=%%H
  SET "fileNameForWMIC=!fileNameForWMIC:\=\\!"
  ECHO !fileNameForWMIC!
  ECHO Goodver !GoodVer!
  rem the following do not perform as expected
  setlocal enabledelayedexpansion
  FOR /F "usebackq skip=1" %%I IN (`wmic datafile where Name^="!fileNameForWMIC!" get Version ^| findstr /r /v "^$"`) DO (
    SET "filever1=%%~I"
    ECHO( !filever1!
  )
  IF /I NOT ["!filever1!"] == ["%GoodVer%"] (
    ECHO "%fileNameForWMIC%" have version^=!filever1! instead of %GoodVer%
    "!7ZAEXE!" a "!TARGET!" "%fileNameForWMIC%"
    SET /A NbError+=1  
  ) ELSE ( "!7ZAEXE!" e "!REFFILE!" -o!LOCATION! "%fileNameForWMIC%" -r)
)  

以下是 verPFM.txt 的一些行

Name                                               Version
c:\program files (x86)\my prog\pfm\intl.dll,0.18.1.0
c:\program files (x86)\my prog\pfm\libeay32.dll,1.0.1.16
c:\program files (x86)\my prog\pfm\libl1sa.dll,1.2.0.1

首先它正确读取了位于 verpfm.txt 文件中的文件名和版本,但是第二个 For/F 无法获取 fileNameForWMIC 变量,因此其余部分无法完成。

批处理文件位于一个目录中,我也将要压缩的 7za.exe 和 verPFM.txt 文件放在该目录中。

NewPFM.7z 包含 verPFM.txt 中列出的文件,批处理的目的是检查 verPFM.txt 中列出的所有文件以及位于“LOCATION”中的文件是否具有与列出的相同的版本,如果不同,则检查存档 PFM.7z 中 LOCATION 中的文件并将其替换为 NewPFM.7z 中的文件

我希望构建最终批次并添加反向选项以恢复保存在 PFM.7z 中的文件

如何解决这个问题?提前致谢

答案1

最后在尝试了很多不同的方法之后我得到了这个批次的使用程序。

它按预期工作

@ECHO OFF
ECHO %~dp0
ECHO %~dpnx0
SET fileNameForWMIC=
SET "ZAEXE=7za.exe"
SET ZAEXE=%~dp0%ZAEXE%
IF NOT EXIST %ZAEXE% (
 ECHO 7za.exe is missing please fix it and restart
 GOTO :END
 )
SET DEST="C:\Program Files (x86)\My Prog\PFM"
IF /I "%1"=="/revert" GOTO :REVERT
SET "IMPFILE=verPFM.txt"
SET IMPFILE=%~dp0%IMPFILE%
IF NOT EXIST %IMPFILE% (
  ECHO verPFM.txt is missing please fix it and restart
  GOTO :END
  )
SET "REFFILE=refPFM.7z"
SET REFFILE=%~dp0%REFFILE%
IF NOT EXIST %REFFILE% (
  ECHO refPFM.7z is missing please fix it and restart
  GOTO :END
  )
SET "SOURCE=C:\Program Files (x86)\My Prog\*.*"
SET "TARGET=PFM_ALL.7z"
SET TARGET=%~dp0%TARGET%
rem the whole directory
FOR /D %%X IN ("%SOURCE%") do  %ZAEXE% a "%TARGET%" "%%X"
IF NOT EXIST %TARGET% (
  ECHO PFM_ALL.7z was not created please report
  GOTO :END
  ) ELSE ECHO A complete backup of %SOURCE% is in %TARGET%
  rem change target file
  SET "TARGET=PFM.7z"
  SET TARGET=%~dp0%TARGET%
  SET /A NbError=0
  rem "!7ZAEXE!" a "!TARGET!" @"!IMPFILE!" 
  rem only the important files listed in text file
  setlocal enabledelayedexpansion
  FOR /F "usebackq skip=1 tokens=1,2 delims=," %%G IN ("%IMPFILE%") DO ( 
    rem echo %%G version %%H
    SET fileNameForWMIC=%%G 
    SET GoodVer=%%H
    SET "fileNameForWMIC=!fileNameForWMIC:\=\\!"
    rem ECHO !fileNameForWMIC!
    rem ECHO Goodver !GoodVer!
    call :process "%%G" %%H
    )
  goto :next  
:next
IF %NbError% EQU 0 (
  ECHO All files was already upto date
  GOTO :END
  ) ELSE ( 
    IF NOT EXIST %TARGET% (
      ECHO PFM.7z was not created please report
      GOTO :END
      ) ELSE ( ECHO %NbError% files saved in %TARGET% )
  )   
:END
  SET SOURCE=
  SET TARGET=
  SET fileNameForWMIC=
  SET fileNameForW=
  SET GoodV=
  SET GoodVer=
  SET NbError=
  SET REFFILE=
  SET DEST=
  SET filename=
  EXIT /B 
:process
  SET fileNameForW=%1 
  rem ECHO %fileNameForW%
  SET GoodV=%2
  SET fileNameForW=%fileNameForW:\=\\%
  rem ECHO %fileNameForW%
  rem ECHO Goodv %GoodV%
  SET fileNameForWW=%1 
  rem ECHO %fileNameForWW%
  FOR /F "usebackq skip=1" %%I IN (`wmic datafile where Name^=%fileNameForW% get Version ^| findstr /r /v "^$"`) DO (
  SET "filever1=%%~I"
  rem ECHO( !filever1!
  )
  IF /I NOT ["!filever1!"] == ["%GoodV%"] (
    ECHO %fileNameForW% have version^=%filever1% instead of %GoodV%
    "%ZAEXE%" a "%TARGET%" %fileNameForWW%
    SET /A NbError+=1  
    rem ECHO %fileNameForWW%
    call :getfilename %fileNameForWW%
    "%ZAEXE%" e "%REFFILE%" -o%DEST% !filename! -aoa
    GOTO :EOF
    ) ELSE ( 
    GOTO :EOF
    )
 :getfilename
  SET filename=%~nx1
  rem echo The name of the file is %filename%
  rem set folder=%~dp1
  rem echo It's path is %folder%
  GOTO :EOF
:REVERT
  rem change target file
  SET "TARGET=PFM.7z"
  SET TARGET=%~dp0%TARGET%
  IF NOT EXIST %TARGET% (
   ECHO PFM.7z not found could not revert
   GOTO :END
   ) ELSE (
    "%ZAEXE%" e "%TARGET%" -o%DEST% * -aoa
    GOTO :END
    )

程序:END 首先清理变量,完成批处理

过程 :REVERT 撤消所做的更改,通过调用 batch.cmd /revert 来执行

IMPFILE 是使用与内部用于获取文件版本相同的 wmic 命令创建的,带有 /OUTPUT,然后编辑文件以删除空白字符并将其从 UTF16 转换为 ASCII(使用 notepad++),否则无法读取文件!

相关内容