Você pode compactar um arquivo a partir do prompt de comando usando APENAS o recurso interno do Windows para compactar arquivos?

93

Eu tenho um arquivo em lotes que gera um arquivo de texto. Eu pensei que seria legal se eu pudesse fechar também.

Isso será usado em um ambiente não controlado, por isso não posso fazer suposições sobre a presença de produtos de software de terceiros, como 7-Zip , etc. Isso precisa usar o recurso agora integrado do Windows para compactar arquivos.

    
por Aaron Bush 19.02.2010 / 20:46

11 respostas

81

Aqui está uma solução de todos os arquivos em lote (uma variação da minha outra resposta) que irá compactar um arquivo 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

O acesso de gravação é necessário para o pai da pasta armazenada em TEMPDIR . Como esse geralmente não é o caso da raiz da unidade C TEMPDIR pode ter que ser alterada.

O acesso de gravação também é necessário para a pasta em que o script .bat está (como gera um arquivo).

Além disso, observe que a extensão de arquivo do arquivo compactado deve ser .zip . Tentativas de usar outra extensão podem resultar em um erro de script. Em vez disso, gere o arquivo .zip e renomeie-o.

    
por 22.02.2010 / 18:28
35

é possível para arquivos zip sem a instalação de qualquer adicional software (eu testei). A solução é:

Execute isto em uma janela de linha de comando para criar um arquivo zip chamado C:\someArchive.zip contendo todos os arquivos na pasta C:\test3 :

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

Onde o arquivo 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 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

Eu não testei caminhos e nomes de arquivos contendo espaços. Pode funcionar se aspas são colocados em torno dos parâmetros da linha de comando.

Como funciona: a funcionalidade zip integrada no Windows (Windows XP e posterior?) é exposto através de interfaces COM do shell do Windows , explorer.exe - que é a parte "Shell.Application". Essa interface COM pode ser usada em um script VBScript porque esse script pode acessar os componentes COM. Para tornar o script totalmente autocontido, cria um arquivo ZIP vazio para começar (também é possível criar um arquivo ZIP vazio e copiá-lo para o sistema de destino junto com o script VBScript).

O VBScript foi instalado por padrão em todos os desktops lançamento do Microsoft Windows desde o Windows 98.

CScript.exe faz 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. Ele também é instalado se o Internet Explorer 5 (ou uma versão posterior) estiver instalado.

    
por 20.02.2010 / 16:48
11

Se você estiver aberto ao uso do PowerShell , os recursos de zip estarão disponíveis no .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)}
    
por 19.02.2010 / 22:59
7

Você pode eliminar o risco de tempo limite durante a compactação pesquisando a existência da janela de diálogo de compactação. Esse método também lida com o cancelamento do usuário na janela de compactaçã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
    
por 23.11.2011 / 01:47
4

Se você conseguir instalar o Kit de recursos Ferramentas , você encontrará uma ferramenta de linha de comando chamada COMPRESS que pode criar arquivos compactados como o 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.
    
por 19.02.2010 / 21:29
3
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop
    
por 07.08.2012 / 09:46
2

Vários arquivos / diretórios com código simplificado.

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

arquivo 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
    
por 05.11.2012 / 22:06
2

Esta é uma mutação da resposta aceita. Eu faço uma tonelada de tarefas de automação em milhares de arquivos por vez, então eu não posso apenas dormir por 2 segundos e não me importar com isso. Obtive a solução alternativa aqui , que também é semelhante à resposta de Jiří Kočara aqui .

Isso fará com que a pasta de destino receba um ping a cada 200 ms, o que é aproximadamente o mais rápido que a Microsoft diz para verificar se há atualizações do 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
    
por 07.06.2017 / 23:53
1

Aqui estou minha tentativa de resumir as capacidades internas das janelas para compactação e descompactação - link

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

No que diz respeito ao shell.application e ao WSH, eu preferi os jscript como ele permite um arquivo híbrido em lote / jscript (com extensão .bat) que não requer arquivos temporários.Eu coloquei os recursos de descompactação e zip em um arquivo, além de mais alguns recursos.

    
por 22.01.2015 / 13:31
0

Se no Windows 8 ou no Windows Server 2012 você terá o PowerShell e o .NET 4.5, você pode fazer isso:

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 você precisar de um ajudante para chamar o PowerShell para você, o diretório será o primeiro argumento e o nome do zip será o segundo):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"
    
por 02.08.2016 / 13:19
-5

A linha de comando do Windows agora fornece o comando compact que, até onde eu sei, é nativo do Windows. Isso deve atender aos requisitos solicitados, a menos que eu tenha perdido alguma coisa.

    
por 31.05.2013 / 21:54