Können Sie eine Datei über die Eingabeaufforderung komprimieren, indem Sie NUR die in Windows integrierte Funktion zum Komprimieren von Dateien verwenden?


111

Ich habe eine Batch-Datei, die eine Textdatei ausgibt. Ich dachte, es wäre schön, wenn ich es auch reißen könnte.

Dies wird in einer unkontrollierten Umgebung verwendet, sodass ich keine Vermutungen über das Vorhandensein von Softwareprodukten von Drittanbietern wie 7-Zip usw. anstellen kann. Dazu muss die jetzt in Windows integrierte Funktion zum Komprimieren von Dateien verwendet werden.


1
Können Sie Powershell- oder WSH-Skripte verwenden? Dies ist möglicherweise die einzige Möglichkeit, die in Windows integrierte ZIP-Verarbeitung über die Befehlszeile zu verwenden. Andernfalls benötigen Sie, wie Molly betont, ein Drittanbieter-Tool.
Quack Quijote

1
Sie senden also jemandem eine Batch-Datei und können ihm keine winzigen statisch verknüpften gzip.exe senden?
Akira

Die Frage des OP ist ausgezeichnet (trotz @quackquixotes seltsamer Anschuldigung). Da Windows dies mit einem einzigen Klick unter SendTo bereitstellt, sollte es einen Befehl geben, der in einer BAT-Datei verwendet werden kann. Es ist also eine gute Frage, auch wenn die Antwort Nein lautet und man (lächerlich) auf ein Tool eines Drittanbieters zurückgreifen muss, das möglicherweise gleichwertig ist oder nicht.
Jon Coombs

Dieser Link von Tomas hat ein gut geschriebenes Skript, um den Inhalt eines Ordners zu komprimieren. Damit es funktioniert, kopieren Sie das Skript einfach in eine Batch-Datei und führen Sie es aus, indem Sie den zu komprimierenden Ordner (Quelle) angeben. Das Zielverzeichnis muss nicht erwähnt werden, da es standardmäßig im Skript für Desktop ("% USERPROFILE% \ Desktop") festgelegt ist
Abhijeet

3
Das einfachste wäre, in einer cmd-Eingabeaufforderung: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip(es funktioniert auch mit Ordner)
ThomasGuenet

Antworten:


85

Hier ist eine All-Batch-Dateilösung (eine Variante meiner anderen Antwort), mit der eine Datei mit dem Namen komprimiert c:\ue_english.txtund abgelegt wird 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

Schreibzugriff ist auf das übergeordnete Element des Ordners erforderlich, in dem gespeichert ist TEMPDIR. Da dies häufig nicht der Fall ist, muss das Stammverzeichnis von Laufwerk C TEMPDIRmöglicherweise geändert werden.

Schreibzugriff ist auch für den Ordner erforderlich, in dem sich das .batSkript befindet (da dort eine Datei generiert wird).

Beachten Sie auch, dass die Dateierweiterung für die komprimierte Datei sein muss .zip. Der Versuch, eine andere Erweiterung zu verwenden, kann zu einem Skriptfehler führen. Generieren Sie stattdessen die .zipDatei und benennen Sie sie um.


3
@quack Ich hatte die Hoffnung auf einen obskuren Befehl, von dem ich nichts wusste. Ich kann sehen, wie Sie vielleicht feststellen, dass eine schwierige Anforderung, wenn sie nicht existiert, nicht bedeutet, jemanden auszuschalten.
Aaron Bush

@PeterMortensen: Es kann interessant sein oder auch nicht, wie sehr dies mit Powershell vereinfacht wird. Hier ist ein 5-write-zip zeiliges Beispiel , aber es gibt auch ein Cmdlet, das von der Pscx heruntergeladen werden kann .
Tamara Wijsman

Ich habe die zip.exe und cywin1.dll (3mb) verwendet, um die Postleitzahl zu erfüllen, und die Verwendung ist eine Zeile ... aus der Postleitzahl selbst, um einen Batchcode zu verwenden. Ich weiß, kann eine PHP-Bancompile mit Argv verwenden und eine Datei an sie übergeben. Hört sich cool an. "A zip from windows command line" ist ein alter Science-Fiction-Film, oder?
erm3nda

Warum müssen wir einen temporären Ordner verwenden TEMPDIR? Ich denke, Ihre Absicht ist es, die Datei FILETOZIPin einen Ordner zu packen, oder?
Nam G VU

@Peter Mortensen, ich weiß, das ist ein alter Thread, und das ist fast das, wonach ich suche. Gibt es eine Option, um eine große Datei in kleinere Blöcke zu komprimieren?
JohnG

38

Es ist möglich, Dateien ohne Installation zusätzlicher Software zu komprimieren (ich habe es getestet). Die Lösung ist:

Führen Sie dies in einem Befehlszeilenfenster aus, um eine ZIP-Datei mit dem Namen zu erstellen, C:\someArchive.zipdie alle Dateien im Ordner enthält C:\test3:

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

Wo Datei zip.vbsenthält:

' 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

Ich habe es nicht auf Pfade und Dateinamen getestet, die Leerzeichen enthalten. Es kann funktionieren, wenn die Befehlszeilenparameter in Anführungszeichen gesetzt werden.


So funktioniert es: Die integrierte Zip-Funktionalität in Windows (Windows XP und höher?) Wird über COM- Schnittstellen von der Windows-Shell explorer.exe verfügbar gemacht - das ist der Teil "Shell.Application". Diese COM-Schnittstelle kann von einem VBScript- Skript aus verwendet werden, da ein solches Skript auf COM-Komponenten zugreifen kann. Damit das Skript vollständig in sich geschlossen ist, wird zunächst eine leere ZIP-Datei erstellt (Sie können auch eine leere ZIP-Datei erstellen und diese zusammen mit dem VBScript-Skript auf das Zielsystem kopieren).

VBScript wurde seit Windows 98 standardmäßig in jeder Desktop-Version von Microsoft Windows installiert.

CScript.exeist ein Teil von Windows Script Host . Windows Script Host wird standardmäßig unter Windows 98 und höheren Versionen von Windows verteilt und installiert. Es wird auch installiert, wenn Internet Explorer 5 (oder eine neuere Version) installiert ist.


1
+1 Gute Lösung, die "Just Run" wird, aber ich wähle BAT aus mehreren anderen Gründen nicht aufgeführt. Daher würde ich eine BAT-Lösung vorziehen.
Aaron Bush

4
@Aaron Bush: Dieses Skript und Beaner's stellen beide einen Befehl zur Verfügung, mit dem eine Datei in der Befehlszeile komprimiert wird. Dabei werden die in Windows eingebauten Funktionen verwendet. Sie können diesen Befehl wie jeden anderen Befehl zu einer Batchdatei hinzufügen.
Quack Quijote

Beachten Sie, dass die übergebenen Pfade absolut und nicht relativ sein müssen. Ich musste auch die Techniken in der Antwort hier verwenden: stackoverflow.com/q/1645843/99640
Chuck Wilbur

Pfade müssen absolut sein und es scheint zufällig zu scheitern :(
kixorz

Dies sollte als Antwort ausgewählt werden.
Der Herzog von Marshall Donnerstag,

12

Wenn Sie bereit sind , PowerShell zu verwenden , stehen in .NET 2.0 Zip-Funktionen zur Verfügung (PowerShell ist .NET). Hier ist ein Beispiel ( Quelle ) für 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)}

Dies ist im Grunde das Gleiche wie der CScript-Code in anderen Antworten. Es werden keine .NET-Funktionen verwendet (und .NET bietet sowieso keine ZIP-Unterstützung). Ich vermute, dass dies auch für das Timing-Problem von Bedeutung sein könnte.
Robert Schmidt

2
Die .NET System.IO.Compression.ZipFile-Klasse wurde in Version 4.5 hinzugefügt.
Concrete Gannet

7

Sie können das Risiko einer Zeitüberschreitung während der Komprimierung beseitigen, indem Sie das Vorhandensein des Komprimierungsdialogfensters abfragen. Diese Methode behandelt auch den Benutzer, der das Komprimierungsfenster verlässt.

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. Diese " .Sleep(whatever)" Code-Affen machen mich krank.
ivan_pozdeev

1
Wenn ich ein vbs mit der obigen Logik zum Warten starte, wie wird dies gehandhabt, wenn es über eine geplante Aufgabe gestartet wird (bei der kein Benutzer physisch angemeldet ist)
Wes

5

Wenn Sie die Resource Kit-Tools installieren können, finden Sie ein Befehlszeilentool namens COMPRESS, mit dem komprimierte Archivdateien wie zip erstellt werden können.

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 Löst Dinge nicht wirklich, ist aber trotzdem gut zu wissen.
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

genau das, wonach ich gesucht habe .. aber es gibt mir einen Fehler "auf leere Zip-Datei fehlt"
Sonic Soul

Aus irgendeinem Grund wird dies nie inkrementiert, wenn ich objShell.NameSpace( ZipFile ).Items.Countinnerhalb der Schleife drucke, ist es immer 0, obwohl die Zip-Datei erstellt wurde und der erwartete Inhalt darin enthalten ist ...
Thom Nichols

2

Mehrere Dateien / Verzeichnisse mit vereinfachtem Code.

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

zip.vbs Datei

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

Dies ist eine Mutation der akzeptierten Antwort. Ich erledige eine Menge Automatisierungsaufgaben mit bis zu Tausenden von Dateien gleichzeitig, sodass ich nicht nur 2 Sekunden schlafen kann und mich nicht darum kümmere. Ich habe hier die Problemumgehung gefunden , die auch Jiří Kočaras Antwort hier ähnelt .

Dies führt dazu, dass der Zielordner alle 200 ms gepingt wird, was ungefähr so ​​schnell ist, wie Microsoft sagt, um nach FS-Updates zu suchen.

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

Hier ist mein Versuch, die integrierten Funktionsfenster für die Komprimierung und Dekomprimierung zusammenzufassen: https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folder -mit-batch-f

Mit ein paar vorgegebenen Lösungen, die auf fast jeder Windows-Maschine funktionieren sollten.

In Bezug auf die Shell.Application und WSH zog ich die jscript , da es eine Hybrid - batch / JScript - Datei (mit Erweiterung .bat) ermöglicht es, dass nicht Temp erfordern files.I've setzen unzip und Zip - Funktionen in einer Datei plus ein paar mehr Features .


0

Wenn Sie unter Windows 8 oder Windows Server 2012 über PowerShell und .NET 4.5 verfügen, können Sie dies folgendermaßen tun:

zip.ps1 (Verwendung :)-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 (wenn Sie einen Helfer benötigen, um PowerShell für Sie aufzurufen, ist das Verzeichnis das erste Argument und der Zip-Name das zweite):

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

0

Windows 10 Build 17063 oder höher ist im Lieferumfang von tar.exe enthalten, das über die Befehlszeile mit zip arbeiten kann.

tar.exe -xf archive.zip

oder um ein Archiv zu erstellen

tar.exe -cf Test.zip Test

-5

Die Windows-Befehlszeile bietet jetzt den kompakten Befehl, der, soweit ich das beurteilen kann, in Windows integriert ist. Das sollte den gewünschten Anforderungen entsprechen, es sei denn, ich habe etwas verpasst.


9
compactexistiert seit XP und ist ein Tool zur Verwaltung der NTFS-Komprimierung
Der Hochstapler
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.