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

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

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

14 ответов

Решение

Вот решение для всех пакетных файлов (вариант моего другого ответа), которое заархивирует файл с именем 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 файл и переименуйте его.

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

Запустите это в окне командной строки, чтобы создать 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 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 (или более поздняя версия).

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

tar.exe -xf archive.zip

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

tar.exe -cf Test.zip Test

Если вы открыты для использования 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)}

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

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

Для этого есть одна простая команда cmd.exe (через PowerShell v5.0+).

Чтобы заархивировать:

powershell Compress-Archive -LiteralPath 'C:\mypath\testfile.txt' -DestinationPath "C:\mypath\Test.zip"

Чтобы распаковать:

powershell Expand-Archive -LiteralPath "C:\mypath\Test.Zip" -DestinationPath "C:\mypath" -Force

Источники:

Особая благодарность @Ramhound.

Если вы сможете установить 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.
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop

Если в 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'"

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

Это приведет к тому, что папка назначения будет проверяться каждые 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

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

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

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

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

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

Начиная со сборки 1803 (март 2018 г.), Windows включаетtar.exeвC:\Windows\System32\tar.exe. Tar можно использовать для создания и извлечения zip-файлов. Типtar /?для получения дополнительной информации.

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

Другие вопросы по тегам