Я закончил писать короткий пакетный сценарий, который автоматически распакует и удалит все заархивированные файлы в папке загрузок.
Я работаю отлично, за исключением случаев, когда представлены zip-файлы, в имени которых есть пробел.
Я не могу точно сказать, в чем проблема, поэтому я помещу здесь весь сценарий, поскольку он довольно короткий.
@echo off
setlocal
cd C:\Users\%username%\Downloads\
del /q search_result.txt
for /r %%i in (*.zip) do (
echo %%~nxi >> search_result.txt
)
for /f %%i in ("search_result.txt") do set asdf=%%~zi
if %asdf% gtr 0 (
goto unzipAgain
)
end
:unzipAgain
set /p zippedFile=< search_result.txt
Call :UnZipFile "C:\Users\%username%\Downloads\%zippedFile:~0,-4%" "C:\Users\%username%\Downloads\%zippedFile%"
exit /b
:UnZipFile <ExtractTo> <newzipfile>
cd /d %~dp0
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%
del C:\Users\%username%\Downloads\%zippedFile%
cd C:\Users\%username%\Downloads\
findstr /V %zippedFile% search_result.txt > newfile.txt
xcopy newfile.txt search_result.txt /y >nul
del newfile.txt /f /q >nul
for /f %%i in ("search_result.txt") do set asdf=%%~zi
if %asdf% gtr 0 (
goto unzipAgain
)
del search_result.txt
ТИА, Эвин
n.b VBScript не мой, и я не знаю, как он работает, я просто использовал его вместе со своим собственным кодом.
Я удивлен, что он также правильно работает с файлами, не содержащими пробелов! Попробуйте прочитать справку по команде For
, (особенно UseBackQ
и Tokens
или Delims
). Вы также должны научиться защищать строки, используя двойные кавычки, где это возможно.
Я тестировал Vbscript с файлами, в имени которых были пробелы, и он работал нормально. Я не использовал ваш запутанный пакетный код.
Если вы собираетесь использовать Vbscript, я бы посоветовал вам переписать его, чтобы он принимал аргументы в скрипт при его запуске, вместо того, чтобы воссоздавать скрипт с переменными командного файла для каждого файла, который вам нужно обработать. Ваш текущий командный файл СУПЕР неэффективен. Не говоря уже о том, что вы совершаете непрерывные ВЫЗОВЫ, никогда не возвращаясь к родительскому процессу, прежде чем сделать еще один ВЫЗОВ.
Не уверен, почему вы используете FOR /R
, потому что ваш сценарий никогда не будет обрабатывать zip-файл в подпапке текущего каталога. Если вы просто обрабатываете файлы в одной папке, опция /R
вам не нужна.
Честно говоря, я не могу сказать, что в своих самых смелых мечтах я бы попытался закодировать то, что вы сделали вот так. Вы буквально сделали гору из кротового холма. Вы не могли бы усложнить себе жизнь. Думаю, как только вы увидите эти три примера кода, вы поймете, почему вам следует придерживаться K.I.S.S. принцип.
Код Vbscript, который у вас есть, отлично работает с пробелами. Вероятно, что-то было в коде вашего командного файла, что-то напортачило. Вы можете значительно упростить свой код, используя одну единственную команду FOR
и просто создав Vbscript один раз. Я изменил VBscript, чтобы он принимал аргументы командной строки.
@echo off
set "source=C:\Batch\unzip"
CD /D "%source%"
call :createVBS "unzip.vbs"
FOR %%G IN (*.zip) DO (
cscript //nologo "%vbs%" "%source%\%%~nG" "%source%\%%~G"
del "%%~G"
)
del "%vbs%" 2>nul
exit /b
:CreateVBS
set "vbs=%~1"
del "%vbs%" 2>nul
>%vbs% echo Set fso = CreateObject("Scripting.FileSystemObject")
>>%vbs% echo Set objArgs = WScript.Arguments
>>%vbs% echo If NOT fso.FolderExists(objArgs(0)) Then
>>%vbs% echo fso.CreateFolder(objArgs(0))
>>%vbs% echo End If
>>%vbs% echo set objShell = CreateObject("Shell.Application")
>>%vbs% echo set FilesInZip=objShell.NameSpace(objArgs(1)).items
>>%vbs% echo objShell.NameSpace(objArgs(0)).CopyHere(FilesInZip)
>>%vbs% echo Set fso = Nothing
>>%vbs% echo Set objShell = Nothing
Powershell отсутствует около 10 лет назад. С тех пор было несколько способов распаковать файлы в Powershell. Эта первая версия будет работать, если вы используете версию Powershell до версии 5.
@echo off
set "source=C:\Batch\unzip"
CD /D "%source%"
for %%G in (*.zip) do (
powershell -command "Add-Type -AssemblyName System.IO.Compression.FileSystem;[System.IO.Compression.ZipFile]::ExtractToDirectory('%%~G', '.\%%~nG')"
del "%%~G"
)
В версии 5 Powershell код был значительно упрощен с помощью нового командлета.
@echo off
set "source=C:\Batch\unzip"
CD /D "%source%"
for %%G in (*.zip) do (
powershell Expand-Archive '%%~G' -DestinationPath '.\%%~nG'
del "%%~G"
)
Итак, вы можете видеть, как обращение к Powershell значительно сократило объем кода, который вам нужен в вашем пакетном файле.
Это большой объем кода для выполнения одной очень маленькой задачи. Я понимаю, что половина его используется для создания сценария VBscript, но все остальные строки кода пакетного файла можно свести к минимуму до нескольких строк. Если вы используете Windows 7 или более позднюю версию, я настоятельно рекомендую вам использовать Powershell для распаковки, поскольку это может быть буквально одна строка кода.