Bisakah Anda zip file dari command prompt menggunakan HANYA kemampuan built-in Windows untuk zip file?

111

Saya memiliki file batch yang menghasilkan file teks. Saya pikir akan lebih baik jika saya bisa mengancingkannya juga.

Ini akan digunakan dalam lingkungan yang tidak terkendali, jadi saya tidak dapat membuat asumsi tentang keberadaan produk perangkat lunak pihak ketiga seperti 7-Zip , dll. Ini perlu menggunakan kemampuan Windows yang sekarang ada di dalam untuk zip file.

Aaron Bush
sumber
1
dapatkah Anda menggunakan skrip Powershell atau WSH? itu mungkin satu-satunya cara untuk menggunakan penanganan zip bawaan Windows dari commandline. jika tidak, seperti yang ditunjukkan Molly, Anda memerlukan alat pihak ketiga.
quack quixote
1
jadi Anda mengirim seseorang file batch dan Anda tidak dapat mengirimnya beberapa gzip.exe kecil yang terhubung secara statis?
akira
Pertanyaan OP itu sangat bagus (terlepas dari tuduhan aneh @quackquixote). Karena Windows menyediakan ini sebagai satu klik di bawah SendTo, seharusnya ada perintah yang dapat digunakan dalam file BAT. Jadi itu adalah pertanyaan yang bagus bahkan jika jawabannya adalah TIDAK dan kita harus (dengan konyol) menggunakan alat pihak ketiga yang mungkin setara atau tidak.
Jon Coombs
Ini adalah tautan oleh Tomas yang memiliki skrip yang ditulis dengan baik untuk menyalin isi folder. Untuk membuatnya berfungsi, cukup salin skrip ke file batch dan jalankan dengan menentukan folder yang akan di-zip (sumber). Tidak perlu menyebutkan direktori tujuan karena default dalam skrip ke Desktop ("% USERPROFILE% \ Desktop")
Abhijeet
3
Yang paling sederhana adalah, dalam prompt cmd: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip(berfungsi dengan folder juga)
ThomasGuenet

Jawaban:

85

Berikut ini adalah solusi semua file batch (variasi dari jawaban saya yang lain) yang akan mem-zip sebuah file bernama c:\ue_english.txtdan memasukkannya 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

Diperlukan akses tulis ke induk folder yang disimpan TEMPDIR. Karena hal ini sering tidak berlaku untuk root dari drive C TEMPDIRmungkin harus diubah.

Akses tulis juga diperlukan untuk folder tempat .batskrip berada (karena menghasilkan file di sana).

Perlu diketahui juga bahwa ekstensi file untuk file yang dikompresi harus .zip. Upaya untuk menggunakan ekstensi lain dapat menyebabkan kesalahan skrip. Sebaliknya, hasilkan .zipfile dan ganti namanya.

Peter Mortensen
sumber
3
@ quack saya bertahan dengan harapan akan perintah yang tidak saya ketahui. Saya dapat melihat bagaimana Anda mungkin menemukan bahwa persyaratan yang sulit jika tidak ada, tidak berarti mengeluarkan siapa pun.
Aaron Bush
@PeterMortensen: Mungkin atau mungkin tidak menarik untuk melihat seberapa banyak ini disederhanakan dengan Powershell. Berikut ini adalah contoh 5 baris , tetapi ada juga write-zipcmdlet yang dapat diunduh dari Pscx .
Tamara Wijsman
Saya menggunakan zip.exe dan cywin1.dll (3mb) untuk memenuhi ZIP dan penggunaan adalah satu baris ... dari zip itu sendiri menggunakan beberapa kode batch. Saya tahu bisa menggunakan php bancompile'd dengan argv dan meneruskan file ke sana. Terdengar keren. "Zip dari windows command line" adalah film fiksi ilmiah lama, kan?
erm3nda
Mengapa kita harus menggunakan folder temp TEMPDIR? Saya pikir niat Anda adalah untuk membungkus file FILETOZIPdengan folder, kan?
Nam G VU
@Peter Mortensen, saya tahu ini adalah utas lama, dan ini hampir apa yang saya cari. Apakah ada opsi untuk mengompres satu file besar menjadi potongan yang lebih kecil?
JohnG
38

Hal ini dimungkinkan untuk zip file tanpa instalasi perangkat lunak tambahan (Saya telah diuji). Solusinya adalah:

Jalankan ini di jendela baris perintah untuk membuat file ZIP bernama C:\someArchive.zipberisi semua file di folder C:\test3:

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

Di mana file zip.vbsberisi:

' 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

Saya belum mengujinya untuk jalur dan nama file yang berisi spasi. Mungkin berhasil jika tanda kutip diletakkan di sekitar parameter baris perintah.


Cara kerjanya: fungsi zip bawaan di Windows (Windows XP dan yang lebih baru?) Diekspos melalui antarmuka COM dari shell Windows, explorer.exe - itu adalah bagian "Shell.Application". Antarmuka COM ini dapat digunakan dari skrip VBScript karena skrip tersebut dapat mengakses komponen COM. Untuk membuat skrip sepenuhnya mandiri, ia membuat file ZIP kosong untuk memulai (orang juga bisa membuat file ZIP kosong dan menyalinnya ke sistem target bersama dengan skrip VBScript).

VBScript telah diinstal secara default di setiap rilis desktop Microsoft Windows sejak Windows 98.

CScript.exeadalah bagian dari Host Script Windows . Windows Script Host didistribusikan dan diinstal secara default pada Windows 98 dan versi Windows yang lebih baru. Ini juga diinstal jika Internet Explorer 5 (atau versi yang lebih baru) diinstal.

Peter Mortensen
sumber
1
+1 Solusi bagus yang akan "Just Run", tetapi saya memilih BAT karena beberapa alasan lain yang tidak tercantum. Jadi saya lebih suka solusi BAT.
Aaron Bush
4
@ Harun Bush: skrip ini dan Beaner's keduanya memberikan perintah yang zip file pada commandline, menggunakan fungsi builtin windows, seperti yang diminta. Anda bisa menambahkan perintah itu ke batchfile seperti yang lainnya.
quack quixote
Perhatikan bahwa jalur yang dilalui harus mutlak, bukan relatif. Saya juga harus menggunakan teknik dalam jawabannya di sini: stackoverflow.com/q/1645843/99640
Chuck Wilbur
Paths harus absolut dan tampaknya gagal secara acak :(
kixorz
Ini harus dipilih sebagai jawabannya.
The Duke Of Marshall שלום
12

Jika Anda terbuka untuk menggunakan PowerShell , kapabilitas zip tersedia di .NET 2.0 (PowerShell is .NET). Berikut ini contoh kredit ( sumber ) untuk 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)}
Beaner
sumber
Ini pada dasarnya sama dengan kode CScript di jawaban lain. Tidak ada fitur .NET yang digunakan (dan .NET tidak memiliki dukungan ZIP). Saya menduga ini mungkin juga sensitif terhadap masalah waktu.
Robert Schmidt
2
Kelas .NET System.IO.Compression.ZipFile ditambahkan dalam versi 4.5.
Concrete Gannet
7

Anda dapat menghilangkan risiko penghentian waktu selama kompresi dengan polling untuk keberadaan jendela dialog kompresi. Metode ini juga menangani pembatalan pengguna dari jendela kompresi.

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
George Yockey
sumber
1
+1. Kode-kode itu " .Sleep(whatever)" membuat saya muak.
ivan_pozdeev
1
Jika saya menjalankan vbs dengan logika di atas untuk menunggu, bagaimana ini akan ditangani jika diluncurkan melalui tugas yang dijadwalkan (di mana tidak ada pengguna yang masuk secara fisik.)
Wes
5

Jika Anda dapat menginstal Resource Kit Tools , Anda akan menemukan alat baris perintah yang disebut COMPRESS yang dapat membuat file arsip terkompresi seperti 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.
cowgod
sumber
3
+1 Tidak benar-benar menyelesaikan masalah, tetapi masih bagus untuk diketahui.
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
Jiří Kočara
sumber
persis apa yang saya cari .. tapi itu memberi saya kesalahan "hilang pada file Zip kosong"
Sonic Soul
Untuk beberapa alasan, ini tidak pernah bertambah, jika saya mencetak objShell.NameSpace( ZipFile ).Items.Countdi dalam loop, selalu 0 meskipun file zip dibuat dan memiliki konten yang diharapkan di dalam ...
Thom Nichols
2

Banyak file / direktori dengan kode sederhana.

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
Olc
sumber
2

Ini adalah mutasi dari jawaban yang diterima. Saya melakukan banyak tugas otomasi pada ribuan file sekaligus, jadi saya tidak bisa hanya tidur selama 2 detik dan tidak peduli. Saya mendapatkan solusinya di sini , yang juga mirip dengan jawaban Jiří Kočara di sini .

Ini akan menyebabkan folder tujuan di-ping setiap 200ms, yang kira-kira secepat Microsoft mengatakan untuk memeriksa pembaruan 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
kayleeFrye_onDeck
sumber
1

Inilah upaya saya untuk merangkum jendela kemampuan bawaan untuk kompresi dan uncompression - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders -dengan-batch-f

dengan beberapa solusi yang diberikan yang harus bekerja pada hampir setiap mesin windows.

Mengenai shell.aplikasi dan WSH saya lebih suka jscript karena memungkinkan file batch / jscript hybrid (dengan ekstensi .bat) yang tidak memerlukan file temp. Saya telah menempatkan kemampuan unzip dan zip dalam satu file plus beberapa fitur lainnya .

npocmaka
sumber
0

Jika pada Windows 8 atau Windows Server 2012 Anda akan memiliki PowerShell dan .NET 4.5 sehingga Anda dapat melakukan ini:

zip.ps1 (penggunaan :)-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 (jika Anda membutuhkan penolong untuk memanggil PowerShell untuk Anda, direktori tersebut adalah argumen pertama dan nama zip kedua):

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

Windows 10 build 17063 atau lebih baru dibundel dengan tar.exe yang mampu bekerja dengan zip dari baris perintah.

tar.exe -xf archive.zip

atau untuk membuat arsip

tar.exe -cf Test.zip Test
venimus
sumber
-5

Baris perintah Windows sekarang menyediakan perintah ringkas yang, sejauh yang saya tahu, adalah asli Windows. Itu harus memenuhi persyaratan yang diminta kecuali saya melewatkan sesuatu.

pengguna228211
sumber
9
compactada sejak XP dan merupakan alat untuk mengelola kompresi NTFS
Der Hochstapler