Вы можете заархивировать файл из командной строки, используя встроенную возможность ТОЛЬКО в Windows для архивирования файлов?

111

У меня есть командный файл, который выводит текстовый файл. Я подумал, что было бы неплохо, если бы я тоже мог застегнуть молнию.

Это будет использоваться в неконтролируемой среде, поэтому я не могу делать предположения о наличии сторонних программных продуктов, таких как 7-Zip и т. Д. Для этого необходимо использовать встроенную в Windows возможность архивировать файлы.

Аарон Буш
источник
1
Вы можете использовать скрипты Powershell или WSH? это может быть единственный способ использовать встроенную обработку zip-файлов в Windows из командной строки. в противном случае, как указывает Молли, вам нужен сторонний инструмент.
Квик-кихот
1
Таким образом, вы отправляете кому-то командный файл и не можете отправить ему какой-нибудь крошечный статически связанный gzip.exe?
Акира
Вопрос ОП - отличный вопрос (несмотря на странное обвинение @quackquixote). Поскольку Windows действительно предоставляет это как один щелчок в SendTo, должна быть команда, используемая в файле BAT. Так что это хороший вопрос, даже если ответ «Нет», и нужно (смешно) прибегнуть к использованию стороннего инструмента, который может быть или не быть эквивалентным.
Джон Кумбс
Это ссылка от Томаса с хорошо написанным скриптом для архивирования содержимого папки. Чтобы заставить его работать, просто скопируйте скрипт в командный файл и запустите его, указав папку для архивирования (источник). Нет необходимости упоминать каталог назначения, так как он по умолчанию в скрипте используется для рабочего стола ("% USERPROFILE% \ Desktop")
Abhijeet
3
Проще всего было бы, в командной строке: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip(он работает и с папкой)
ThomasGuenet

Ответы:

85

Вот решение для всех пакетных файлов (вариант моего другого ответа), которое заархивирует файл с именем c:\ue_english.txtи поместит его в C:\someArchive.zip:

set FILETOZIP=c:\ue_english.txt

set TEMPDIR=C:\temp738
rmdir %TEMPDIR%
mkdir %TEMPDIR%
xcopy /s %FILETOZIP% %TEMPDIR%

echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
echo wScript.Sleep 2000 >> _zipIt.vbs

CScript  _zipIt.vbs  %TEMPDIR%  C:\someArchive.zip

pause

Доступ на запись требуется для родителя папки, хранящейся в TEMPDIR. Поскольку это часто не относится к корню диска C, TEMPDIRвозможно, придется изменить.

Доступ для записи также требуется для папки, в которой .batнаходится скрипт (поскольку он генерирует файл там).

Также обратите внимание, что расширение файла для сжатого файла должно быть .zip. Попытки использовать другое расширение могут привести к ошибке сценария. Вместо этого создайте .zipфайл и переименуйте его.

Питер Мортенсен
источник
3
@ Quack Я держался в надежде на какую-то непонятную команду, о которой я не знал. Я вижу, как вы можете обнаружить, что сложное требование, если его не существует, не означало кого-то выпустить.
Аарон Буш
@PeterMortensen: Может быть, а может и не быть интересно посмотреть, насколько это упростится с помощью Powershell. Вот пример из 5 строк , но также существует write-zipкомандлет, который можно загрузить с Pscx .
Тамара Вийсман
Я использовал zip.exe и cywin1.dll (3 МБ), чтобы удовлетворить ZIP, и использование одной строки ... от самого zip использования некоторого пакетного кода. Я знаю, можно использовать php bancompile'd с argv и передать ему файл. Звучит круто. «Zip из командной строки Windows» - это старый научно-фантастический фильм, верно?
erm3nda
Почему мы должны использовать временную папку TEMPDIR? Я думаю, что вы хотите обернуть файл FILETOZIPв папку, верно?
Нам G VU
@ Питер Мортенсен, я знаю, что это старая ветка, и это почти то, что я ищу. Есть ли возможность сжать один большой файл в более мелкие куски?
JohnG
38

Это есть возможность пронестись файлами без установки какого - либо дополнительного программного обеспечения (я тестировал). Решение:

Запустите это в окне командной строки, чтобы создать ZIP-файл, C:\someArchive.zipсодержащий все файлы в папке C:\test3:

CScript  zip.vbs  C:\test3  C:\someArchive.zip

Где файл zip.vbsсодержит:

' Get command-line arguments.
Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

' Create an empty ZIP file.
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")

Set source = objShell.NameSpace(InputFolder).Items

objShell.NameSpace(ZipFile).CopyHere(source)

' Required to let the ZIP command execute
' If this script randomly fails or the ZIP file is not complete,
' just increase to more than 2 seconds
wScript.Sleep 2000

Я не проверял его на пути и имена файлов, содержащие пробелы. Это может работать, если кавычки помещаются вокруг параметров командной строки.


Как это работает: встроенная функция zip в Windows (Windows XP и более поздние версии?) Предоставляется через COM- интерфейсы из оболочки Windows, explorer.exe - то есть части «Shell.Application». Этот интерфейс COM можно использовать из сценария VBScript, поскольку такой сценарий может обращаться к компонентам COM. Чтобы сделать скрипт полностью автономным, он создает пустой ZIP-файл для начала (можно также создать пустой ZIP-файл и скопировать его в целевую систему вместе со сценарием VBScript).

VBScript был установлен по умолчанию в каждой версии Microsoft Windows для настольных компьютеров, начиная с Windows 98.

CScript.exeявляется частью Windows Script Host . Windows Script Host распространяется и устанавливается по умолчанию в Windows 98 и более поздних версиях Windows. Он также устанавливается, если установлен Internet Explorer 5 (или более поздняя версия).

Питер Мортенсен
источник
1
+1 Хорошее решение, которое будет «Просто беги», но я выбираю BAT по ряду других причин, не указанных. Поэтому я бы предпочел решение с использованием НДТ.
Аарон Буш
4
@ Аарон Буш: этот сценарий и Бинер предоставляют команду, которая архивирует файл в командной строке, используя встроенные функции Windows, как требуется. Вы можете добавить эту команду в пакетный файл, как и любой другой.
Квик-кихот
Обратите внимание, что переданные пути должны быть абсолютными, а не относительными. Я должен был также использовать методы в ответе здесь: stackoverflow.com/q/1645843/99640
Чак Уилбур
Пути должны быть абсолютными, и кажется, что они случайно проваливаются :(
kixorz
Это должно быть выбрано в качестве ответа.
Герцог Маршалл שלום
12

Если вы открыты для использования PowerShell , функции zip доступны в .NET 2.0 (PowerShell - это .NET). Вот пример ( источник ) кредита для Майка Ходника :

########################################################
# out-zip.ps1
#
# Usage:
#    To zip up some files:
#       ls c:\source\*.txt | out-zip c:\target\archive.zip $_
#
#    To zip up a folder:
#       gi c:\source | out-zip c:\target\archive.zip $_
########################################################

$path = $args[0]
$files = $input

if (-not $path.EndsWith('.zip')) {$path += '.zip'} 

if (-not (test-path $path)) { 
  set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
} 

$ZipFile = (new-object -com shell.application).NameSpace($path) 
$files | foreach {$zipfile.CopyHere($_.fullname)}
Бинер
источник
Это в основном то же самое, что и код CScript в других ответах. Функции .NET не используются (и .NET в любом случае не поддерживает ZIP). Я подозреваю, что это может также быть чувствительным к проблеме выбора времени.
Роберт Шмидт
2
Класс .NET System.IO.Compression.ZipFile был добавлен в версии 4.5.
Бетонная олуша
7

Вы можете устранить риск тайм-аута во время сжатия, опросив наличие диалогового окна сжатия. Этот метод также обрабатывает отмену пользователем из окна сжатия.

objShell.NameSpace(ZipFile).CopyHere(source)

' Wait for compression window to open
set scriptShell = CreateObject("Wscript.Shell")
Do While scriptShell.AppActivate("Compressing...") = FALSE   
   WScript.Sleep 500 ' Arbitrary polling delay
Loop  

' Wait for compression to complete before exiting script
Do While scriptShell.AppActivate("Compressing...") = TRUE   
   WScript.Sleep 500 ' Arbitrary polling delay
Loop
Джордж Йокей
источник
1
+1. Этот код в стиле обезьяны " .Sleep(whatever)" меня тошнит.
ivan_pozdeev
1
Если я запускаю vbs с вышеупомянутой логикой для ожидания, как это будет обрабатываться, если он запускается через запланированное задание (где физически ни один пользователь не вошел в систему)
Wes
5

Если вы сможете установить Resource Kit Tools , вы найдете инструмент командной строки под названием COMPRESS, который может создавать сжатые архивные файлы, такие как zip.

Microsoft (R) File Compression Utility  Version 5.00.2134.1
Copyright (C) Microsoft Corp. 1990-1999.  All rights reserved.

Compresses one or more files.

COMPRESS [-r] [-d] [-z] Source Destination
COMPRESS -r [-d] [-z] Source [Destination]

  -r            Rename compressed files.
  -d            Update compressed files only if out of date.
  -zx           LZX compression.
  -z            MS-ZIP compression.
  -zq[n]        Quantum compression and optional level
                (in range 1-7, default is 4).
  Source        Source file specification.  Wildcards may be used.
  Destination   Destination file | path specification.
                Destination may be a directory.
                If Source is multiple files and -r is not specified,
                Destination must be a directory.
cowgod
источник
3
+1 На самом деле ничего не решает, но все же полезно знать.
Аарон Буш
3
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop
Иржи Кочара
источник
именно то, что я искал .. но это дает мне ошибку "отсутствует на пустом Zip-файле"
Sonic Soul
По какой-то причине это никогда не увеличивается, если я печатаю objShell.NameSpace( ZipFile ).Items.Countвнутри цикла, он всегда равен 0, даже если zip-файл создан и в нем есть ожидаемое содержимое ...
Том Николс
2

Несколько файлов / каталогов с упрощенным кодом.

cscript zip.vbs target.zip sourceFile1 sourceDir2 ... sourceObjN

файл zip.vbs

Set objArgs = WScript.Arguments
ZipFile = objArgs(0)

' Create empty ZIP file and open for adding
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set zip = CreateObject("Shell.Application").NameSpace(ZipFile)

' Add all files/directories to the .zip file
For i = 1 To objArgs.count-1
  zip.CopyHere(objArgs(i))
  WScript.Sleep 10000 'REQUIRED!! (Depending on file/dir size)
Next
КЮ
источник
2

Это мутация принятого ответа. Я выполняю множество задач по автоматизации одновременно с тысячами файлов, поэтому я не могу просто спать 2 секунды и не заботиться об этом. Я подбирала обходной путь здесь , который также похож на ответ Йиржи Kočara в здесь .

Это приведет к тому, что папка назначения будет проверяться каждые 200 мс, что примерно так же быстро, как говорит Microsoft для проверки обновлений FS.

Set parameters = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
SourceDir = FS.GetAbsolutePathName(parameters(0))
ZipFile = FS.GetAbsolutePathName(parameters(1))
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set shell = CreateObject("Shell.Application")
Set source_objects = shell.NameSpace(SourceDir).Items
Set ZipDest = shell.NameSpace(ZipFile)
Count=ZipDest.Items().Count
shell.NameSpace(ZipFile).CopyHere(source_objects)
Do While Count = ZipDest.Items().Count
    wScript.Sleep 200
Loop
kayleeFrye_onDeck
источник
1

Вот моя попытка обобщить встроенные возможности окон для сжатия и распаковки - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders -с-периодического е

с несколькими данными решениями, которые должны работать практически на каждой машине Windows.

Что касается shell.application и WSH, я предпочел jscript, так как он допускает гибридный пакетный / jscript-файл (с расширением .bat), для которого не требуются временные файлы. Я поместил функции разархивирования и архивирования в один файл, плюс еще несколько функций ,

npocmaka
источник
0

Если в Windows 8 или Windows Server 2012 у вас есть PowerShell и .NET 4.5, вы можете сделать это:

zip.ps1 (использование :)-directory <directory to zip up> -name <zip name> :

param (
    [string]$directory,
    [string]$name
)

Add-Type -Assembly System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($directory, $name, [System.IO.Compression.CompressionLevel]::Optimal, $false)

zip.bat (если вам нужен помощник для вызова PowerShell, каталог является первым аргументом, а имя zip вторым):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"
Hashbrown
источник
0

Windows 10 build 17063 или новее поставляется в комплекте с tar.exe, который способен работать с zip из командной строки.

tar.exe -xf archive.zip

или создать архив

tar.exe -cf Test.zip Test
venimus
источник
-5

Командная строка Windows теперь предоставляет компактную команду, которая, насколько я могу судить, является родной для Windows. Это должно соответствовать требованиям, если я что-то пропустил.

user228211
источник
9
compactсуществует с XP и является инструментом для управления сжатием NTFS
Der Hochstapler