Вы читаете неопределенную переменную %Extension%
, и у вас есть два выражения в левой части ==
в операторе if
, что является синтаксической ошибкой.
Чтобы получить расширение имени файла элемента итерированного по for
петле, используйте ~x
модификатор (тип for /?
в командной строке, чтобы узнать больше о том, что), как %%~xi
в вашем коде:
if /i "%%~xi"==".zip" (...)
Переключатель /i
делает сравнение нечувствительным к регистру, которое рекомендуется здесь, так как Windows обрабатывает имена файлов таким же образом.
Однако в вашей ситуации вам не нужны if
заявление вообще для проверки расширения имени файла, так что вы можете позволить for
сделать эту работу:
for /r %%i in (*.zip) do (...)
Этот цикл Перебирает *.zip
файлов только.
Существует еще одна проблема в вашем коде: подпрограмма :UnZipFile
является частью тела цикла, и поэтому есть и exit /b
внутри цикла.
Подпрограмма должна быть вне цикла. Когда выполняется call
, текущие контексты заключенных в скобки блоков кода не известны в подпрограмме, поэтому он не будет считаться завершенным, как только появится завершение цикла )
10, скорее возникает синтаксическая ошибка. Следовательно, вам нужно переместить )
от самого нижнего уровня до новой строки доexit /b
(если вы поместите его после того, команда exit
сломает цикл).
Поскольку у вас есть setlocal
внутри вашего цикла, то нужно положить также endlocal
(непосредственно перед )
), чтобы не превысить setlocal
вложенности предел.Однако, если вы используете полные пути внутри цикла, вам не нужно setlocal
/endlocal
. Вместо этого я переместил бы setlocal
/endlocal
в подпрограмму, чтобы локализовать переменные среды, используемые в ней.
Я не уверен, что если вы собираетесь перейти в каталог, где скрипт хранится на cd /d %~dp0
, но я думаю, что вы хотите полный путь к текущей итерации *.zip
файла в цикле, не так ли? Если да, удалите команду cd
и используйте %%~fi
в командной строке call
.
Наконец, котировка не является оптимальной на всем протяжении всего кода. Например, всегда рекомендуется указывать пути и имена файлов, так как они могут содержать пробелы или некоторые другие символы, которые интерпретатор команд интерпретирует как разделители или имеет для него какое-то особое значение.
Также в подпрограммах следует процитировать пути, предоставленные в качестве аргументов, и доступ к ним, как "%~1"
, например, чтобы получить их цитироваться (тип call /?
, чтобы увидеть, что ~
удаляет окружающие кавычки potentionally доставлены в командной строке).
И лучший set
синтаксис: set "vbs=%temp%\_.vbs"
; поэтому котировки не становятся частью стоимости, и у вас всегда есть один место для размещения кавычек - а именно, когда чтение (расширение) переменной, например "%vbs%"
.
Наконец, позвольте мне рекомендовать вам использовать отступ, чтобы код стал более разборчивым и ремонтопригодным.
Вот фиксированный код:
@echo off
cd /d %~dp0
for /r %%i in ("*.zip") do (
Call :UnZipFile "G:\NewUpdates\ExtractedStuff" "%%~fi"
)
exit /b
:UnZipFile <ExtractTo> <newzipfile>
setlocal
set vbs="%temp%\_.vbs"
if exist "%vbs%" del /f /q "%vbs%"
>"%vbs%" echo Set fso = CreateObject("Scripting.FileSystemObject")
>>"%vbs%" echo If NOT fso.FolderExists("%~1") Then
>>"%vbs%" echo fso.CreateFolder("%~1")
>>"%vbs%" echo End If
>>"%vbs%" echo set objShell = CreateObject("Shell.Application")
>>"%vbs%" echo set FilesInZip=objShell.NameSpace("%~2").items
>>"%vbs%" echo objShell.NameSpace("%~1").CopyHere(FilesInZip)
>>"%vbs%" echo Set fso = Nothing
>>"%vbs%" echo Set objShell = Nothing
cscript //nologo "%vbs%"
if exist "%vbs%" del /f /q "%vbs%"
endlocal
pause
'% расширение%' не имеет особого смысла. Обычно вы разрешаете указанную недостающую переменную 'if"% var% "==" whatever ". Но вы хотите, чтобы '%% ~ xi' смотрел конец' for /? 'Для справки. –
Или 'for/f 'delims =" %% A in (' dir/b/s c: \ somefolder \ *. Zip ') do echo %% A' См. 'Dir /?', 'For /?'. –
@Noodles ', почему 'for/F'? 'for/R %% i in (* .zip) do' enough ... – aschipfl