Puoi comprimere un file dal prompt dei comandi utilizzando SOLO la funzionalità integrata di Windows per comprimere i file?


111

Ho un file batch che genera un file di testo. Ho pensato che sarebbe bello se potessi comprimerlo anche io.

Questo verrà utilizzato in un ambiente non controllato, quindi non posso fare ipotesi sulla presenza di prodotti software di terze parti come 7-Zip , ecc. Questo deve utilizzare la funzionalità integrata di Windows per comprimere i file.


1
puoi usare lo scripting Powershell o WSH? quello potrebbe essere l'unico modo per usare la gestione zip integrata di Windows dalla riga di comando. altrimenti, come sottolinea Molly, è necessario uno strumento di terze parti.
Quack Quixote,

1
quindi mandi a qualcuno un file batch e non puoi inviargli qualche piccolo gzip.exe staticamente collegato?
Akira,

La domanda del PO è eccellente (nonostante la strana accusa di @quackquixote). Poiché Windows fornisce questo come un singolo clic in SendTo, dovrebbe esserci un comando utilizzabile in un file BAT. Quindi è una buona domanda anche se la risposta è No e si deve (ridicolmente) ricorrere all'uso di uno strumento di terze parti che può essere o non essere equivalente.
Jon Coombs,

Questo link di Tomas ha uno script ben scritto per comprimere il contenuto di una cartella. Per farlo funzionare basta copiare lo script in un file batch ed eseguirlo specificando la cartella da comprimere (sorgente). Non è necessario menzionare la directory di destinazione poiché è predefinita nello script su Desktop ("% USERPROFILE% \ Desktop")
Abhijeet

3
Il più semplice sarebbe, in un prompt cmd: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip(funziona anche con la cartella)
ThomasGuenet,

Risposte:


85

Ecco una soluzione per tutti i file batch (una variante della mia altra risposta) che comprime un file denominato c:\ue_english.txte lo inserisce 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

È richiesto l'accesso in scrittura al genitore della cartella archiviata TEMPDIR. Dato che spesso non è così per la radice dell'unità C TEMPDIRpotrebbe essere necessario cambiare.

L'accesso in scrittura è necessario anche per la cartella in cui si trova lo .batscript (in quanto genera un file lì).

Inoltre, si noti che l'estensione del file compresso deve essere .zip. I tentativi di utilizzare un'altra estensione possono causare un errore di script. Invece, genera il .zipfile e rinominalo.


3
@quack stavo resistendo nella speranza di un oscuro comando che non conoscevo. Vedo come potresti scoprire che un requisito difficile se uno non esiste, non significava mettere fuori gioco nessuno.
Aaron Bush,

@PeterMortensen: potrebbe essere interessante vedere quanto questo sia semplificato con Powershell. Ecco un esempio di 5 righe , ma esiste anche un write-zipcmdlet che può essere scaricato da Pscx .
Tamara Wijsman,

Ho usato zip.exe e cywin1.dll (3mb) per soddisfare lo ZIP e l'utilizzo è a una riga ... dallo zip stesso dell'utilizzo di un codice batch. So che posso usare un php bancompile'd con argv e passarci un file. Figo. "Una zip dalla riga di comando di Windows" è un vecchio film di fantascienza, giusto?
erm3nda,

Perché dobbiamo usare una cartella temporanea TEMPDIR? Penso che la tua intenzione sia quella di avvolgere il file FILETOZIPin una cartella, giusto?
Nam G VU,

@Peter Mortensen, so che questo è un vecchio thread e questo è quasi quello che sto cercando. Esiste un'opzione per comprimere un file di grandi dimensioni in blocchi più piccoli?
Giovanni G.

38

Si è possibile comprimere i file senza l'installazione di alcun software aggiuntivo (ho provato). La soluzione è:

Eseguilo in una finestra della riga di comando per creare un file ZIP denominato C:\someArchive.zipcontenente tutti i file nella cartella C:\test3:

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

Dove il file zip.vbscontiene:

' 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

Non l'ho testato per percorsi e nomi di file contenenti spazi. Può funzionare se le virgolette sono inserite attorno ai parametri della riga di comando.


Come funziona: la funzionalità zip integrata in Windows (Windows XP e versioni successive?) È esposta attraverso le interfacce COM dalla shell di Windows, explorer.exe, ovvero la parte "Shell.Application". Questa interfaccia COM può essere utilizzata da uno script VBScript perché tale script può accedere ai componenti COM. Per rendere lo script completamente autonomo crea un file ZIP vuoto per iniziare (si potrebbe anche creare un file ZIP vuoto e copiarlo nel sistema di destinazione insieme allo script VBScript).

VBScript è stato installato per impostazione predefinita in ogni versione desktop di Microsoft Windows da Windows 98.

CScript.exefa parte di Windows Script Host . Windows Script Host è distribuito e installato per impostazione predefinita su Windows 98 e versioni successive di Windows. Viene installato anche se è installato Internet Explorer 5 (o versione successiva).


1
+1 Buona soluzione che sarà "Just Run", ma ho scelto BAT per diversi altri motivi non elencati. Quindi preferirei una soluzione BAT.
Aaron Bush,

4
@Aaron Bush: questo script e Beaner forniscono entrambi un comando che comprime un file sulla riga di comando, usando le funzioni integrate di Windows, come richiesto. puoi aggiungere quel comando a un file batch come qualsiasi altro.
Quack Quixote,

Si noti che i percorsi passati devono essere assoluti, non relativi. Ho dovuto usare anche le tecniche nella risposta qui: stackoverflow.com/q/1645843/99640
Chuck Wilbur,

I percorsi devono essere assoluti e sembra fallire casualmente :(
kixorz,

Questo dovrebbe essere selezionato come risposta.
The Duke Of Marshall

12

Se si è aperti all'uso di PowerShell , le funzionalità zip sono disponibili in .NET 2.0 (PowerShell è .NET). Ecco un esempio di credito ( fonte ) a 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)}

Questo è fondamentalmente la stessa cosa del codice CScript in altre risposte. Non viene utilizzata alcuna funzionalità .NET (e .NET non ha comunque il supporto ZIP). Sospetto che questo potrebbe anche essere sensibile al problema dei tempi.
Robert Schmidt,

2
La classe .NET System.IO.Compression.ZipFile è stata aggiunta nella versione 4.5.
Gannet concreto

7

È possibile eliminare il rischio di timeout durante la compressione eseguendo il polling per l'esistenza della finestra di dialogo della compressione. Questo metodo gestisce anche l'annullamento dell'utente dalla finestra di compressione.

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. Quei codici " .Sleep(whatever)" in stile scimmia mi fanno star male.
ivan_pozdeev,

1
Se sto eseguendo un vbs con la logica di cui sopra per l'attesa, come verrà gestito se avviato tramite un'attività pianificata (in cui nessun utente è connesso fisicamente.)
Wes

5

Se sei in grado di installare gli strumenti del Resource Kit , troverai uno strumento da riga di comando chiamato COMPRESS che può creare file di archivio compressi come 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
+1 Non risolve davvero le cose, ma è comunque buono a sapersi.
Aaron Bush,

3
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop

esattamente quello che stavo cercando .. ma mi dà un errore "mancante nel file zip vuoto"
Sonic Soul

Per qualche motivo questo non aumenta mai, se stampo objShell.NameSpace( ZipFile ).Items.Countall'interno del ciclo, è sempre 0 anche se il file zip è stato creato e ha i contenuti previsti all'interno ...
Thom Nichols

2

Più file / directory con codice semplificato.

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

file 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

Questa è una mutazione della risposta accettata. Faccio un sacco di attività di automazione su un massimo di migliaia di file alla volta, quindi non riesco a dormire solo per 2 secondi e non mi interessa. Ho raccolto la soluzione qui , che è anche simile alla risposta di Jiří Kočara qui .

Questo causerà il ping della cartella di destinazione ogni 200 ms, che è approssimativamente più veloce di quanto Microsoft dice di verificare la presenza di aggiornamenti di 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

1

Ecco un mio tentativo di riassumere le finestre delle funzionalità integrate per la compressione e la decompressione - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders -con-batch-f

con alcune soluzioni fornite che dovrebbero funzionare su quasi tutti i computer Windows.

Per quanto riguarda shell.application e WSH ho preferito jscript in quanto consente un file batch / jscript ibrido (con estensione .bat) che non richiede file temporanei. Ho inserito le funzionalità di decompressione e zip in un file più alcune altre funzionalità .


0

Se su Windows 8 o Windows Server 2012 avrai PowerShell e .NET 4.5, quindi puoi farlo:

zip.ps1 (utilizzo :)-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 hai bisogno di un aiuto per chiamare PowerShell per te, la directory è il primo argomento e il nome zip secondo):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"

0

La build 17063 o successiva di Windows 10 è fornita in bundle con tar.exe che è in grado di funzionare con zip dalla riga di comando.

tar.exe -xf archive.zip

o per creare un archivio

tar.exe -cf Test.zip Test

-5

La riga di comando di Windows ora fornisce il comando compatto che, per quanto posso dire, è nativo di Windows. Ciò dovrebbe soddisfare i requisiti richiesti a meno che non mi sia perso qualcosa.


9
compactesisteva da XP ed è uno strumento per gestire la compressione NTFS
Der Hochstapler,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.