2010-02-19 19:46:23 +0000 2010-02-19 19:46:23 +0000
113
113

É possível zipar um ficheiro a partir do prompt de comando usando SOMENTE a capacidade integrada do Windows para zipar ficheiros?

Tenho um ficheiro de lote que emite um ficheiro de texto. Achei que seria bom se pudesse zipá-lo também.

Isto será utilizado num ambiente não controlado, por isso não posso fazer suposições sobre a presença de produtos de software de terceiros tais como 7-Zip , etc. Isto precisa de utilizar a capacidade agora incorporada do Windows para zipar ficheiros.

Respostas (12)

86
86
86
2010-02-22 17:28:45 +0000

Aqui está uma solução de ficheiro batch (uma variação da minha outra resposta) que irá zipar um ficheiro chamado c:\ue_english.txt e colocá-lo em 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

Write access is required to the parent of the folder stored in TEMPDIR. Como muitas vezes este não é o caso da raiz da unidade C TEMPDIR pode ter de ser alterada.

O acesso de escrita também é necessário para a pasta onde se encontra o script .bat (uma vez que aí gera um ficheiro).

Além disso, tenha em atenção que a extensão do ficheiro comprimido deve ser .zip. Tentativas de utilizar outra extensão podem resultar num erro de script. Em vez disso, gere o ficheiro .zip e dê-lhe um novo nome.

40
40
40
2010-02-20 15:48:33 +0000

É possível zipar ficheiros sem instalação de qualquer software adicional (testei-o). A solução é:

Execute-o numa janela de linha de comando para criar um ficheiro ZIP chamado C:\someArchive.zip contendo todos os ficheiros na pasta C:\test3:

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

Onde o ficheiro zip.vbs contém:

' 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

Não o testei para caminhos e nomes de ficheiros contendo espaços. Pode funcionar se forem colocadas aspas em torno dos parâmetros da linha de comando.


Como funciona: a funcionalidade zip integrada no Windows (Windows XP e posteriores?) é exposta através das interfaces COM da shell do Windows, explorer.exe - que é a parte “Shell.Application”. Esta interface COM pode ser usada a partir de um script VBScript porque esse script pode acessar os componentes COM. Para tornar o script totalmente auto-contido ele cria um arquivo ZIP vazio para começar (pode-se também criar um arquivo ZIP vazio e copiá-lo para o sistema alvo junto com o script VBScript).

VBScript foi instalado por padrão em cada versão desktop do Microsoft Windows desde Windows 98.

CScript.exe é parte do Windows Script Host . O Windows Script Host é distribuído e instalado por padrão no Windows 98 e em versões posteriores do Windows. Também é instalado se Internet Explorer 5 (ou uma versão posterior) estiver instalado.

12
12
12
2010-02-19 21:59:36 +0000

Se estiver aberto a utilizar * PowerShell **, as capacidades zip estão disponíveis em .NET 2.0 (PowerShell é .NET). Aqui está um exemplo fonte ) crédito para Mike Hodnick:

########################################################
# 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)}
7
7
7
2011-11-23 00:47:36 +0000

É possível eliminar o risco de interrupção do tempo durante a compressão através de uma sondagem para a existência da janela de diálogo de compressão. Este método também trata do cancelamento pelo utilizador da janela de compressão.

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
5
5
5
2010-02-19 20:29:14 +0000

Se for capaz de instalar o Resource Kit Tools , encontrará uma ferramenta de linha de comando chamada COMPRESS que pode criar ficheiros de arquivo comprimidos como 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.
3
3
3
2012-08-07 07:46:33 +0000
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop
2
2
2
2017-06-07 21:53:59 +0000

Esta é uma mutação da resposta aceite. Faço uma tonelada de tarefas de automação em até milhares de ficheiros de cada vez, por isso não consigo dormir durante 2 segundos e não me importo com isso. Eu peguei o trabalho aqui , que também é similar à resposta do Jiří Kočara aqui .

Isto fará com que a pasta de destino seja pingada a cada 200ms, o que é aproximadamente tão rápido quanto a Microsoft diz para checar por atualizações de 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
2
2
2
2012-11-05 21:06:59 +0000

Vários ficheiros / directórios com código simplificado.

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

ficheiro 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
1
1
1
2015-01-22 12:31:49 +0000

Aqui a minha tentativa de resumir as capacidades das janelas de compressão e descompressão - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders-with-batch-f

com algumas soluções que devem funcionar em quase todas as máquinas windows.

No que diz respeito ao shell.application e WSH preferi o jscript porque permite um ficheiro híbrido batch/jscript (com extensão .bat) que não requer ficheiros temporários.

1
1
1
2019-08-20 13:24:16 +0000

O Windows 10 build 17063 ou posterior é agrupado com tar.exe que é capaz de trabalhar com zip a partir da linha de comando.

tar.exe -xf archive.zip

ou para criar arquivo

tar.exe -cf Test.zip Test
1
1
1
2016-08-02 11:19:52 +0000

Se em Windows 8 ou Windows Server 2012 terá PowerShell e .NET 4.5 para que o possa fazer:

zip.ps1 (uso: -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 (se precisar de um ajudante para chamar PowerShell para si, o directório é o primeiro argumento e o nome postal o segundo):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"
-4
-4
-4
2013-05-31 19:54:34 +0000

A linha de comando do Windows fornece agora o comando compacto que, tanto quanto posso dizer, é nativo do Windows. Isso deverá satisfazer os requisitos solicitados, a menos que me tenha escapado alguma coisa.