題 您是否可以使用Windows內置的zip文件功能從命令提示符壓縮文件?


我有一個輸出文本文件的批處理文件。我覺得如果我能拉上它也會很好。

這將用於不受控制的環境中,因此我無法對第三方軟件產品的存在進行假設,例如 的7-Zip這需要使用Windows現在內置的zip文件功能。


93
2018-02-19 19:46


起源


你可以使用Powershell或WSH腳本嗎?這可能是從命令行使用Windows內置zip處理的唯一方法。否則,正如莫莉指出的那樣,你需要一個第三方工具。 - quack quixote
所以你發送一個批處理文件,你不能發送一些微小的靜態鏈接gzip.exe? - akira
OP的問題非常好(儘管@quackquixote的指責很奇怪)。由於Windows確實在SendTo下單擊提供,因此 應該 成為BAT文件中可用的命令。因此,即使答案為否,這也是一個很好的問題,而且必須(荒謬地)使用可能相同或不相同的第三方工具。 - Jon Coombs
這是 鏈接 by Tomas有一個寫得很好的腳本來壓縮文件夾的內容。要使其工作,只需將腳本複製到批處理文件中,然後通過指定要壓縮的文件夾(源)來執行它。無需提及目標目錄,因為它在腳本中默認為Desktop(“%USERPROFILE%\ Desktop”) - Abhijeet
最簡單的是,在cmd提示符下: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip (它也適用於文件夾) - ThomasGuenet


答案:


這是一個所有批處理文件解決方案(我的另一個答案的變體),它將壓縮一個名為的文件 c:\ue_english.txt 並把它放進去 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

存儲在其中的文件夾的父級需要寫訪問權限 TEMPDIR。因為驅動器C的根通常不是這種情況 TEMPDIR 可能不得不改變。

該文件夾也需要寫訪問權限 .bat 腳本在(因為它在那裡生成一個文件)。

此外,請注意壓縮文件的文件擴展名必須是 .zip。嘗試使用其他擴展名可能會導致腳本錯誤。相反,生成 .zip 文件並重命名。


81
2018-02-22 17:28



@quack我抱著一些我不知道的模糊命令。我可以看到,如果一個人不存在,你怎麼會發現一個困難的要求,並不意味著把任何人排除在外。 - Aaron Bush
@PeterMortensen:看看Powerershell簡化了多少,可能會或者可能沒有意義。 這是一個5行的例子,但也存在 write-zip 可以從中下載的cmdlet Pscx。 - Tom Wijsman
我使用zip.exe和cywin1.dll(3mb)來滿足ZIP和使用是一行......來自zip本身使用一些批處理代碼。我知道可以使用帶有argv的php bancompile並將文件傳遞給它。聽起來很酷。 “來自Windows命令行的拉鍊”是一部古老的科幻電影,對吧? - erm3nda
為什麼我們必須使用臨時文件夾 TEMPDIR?我認為你的意圖是包裝文件 FILETOZIP 通過文件夾對嗎? - Nam G VU
@Peter Mortensen,我知道這是一個老線程,這幾乎是我正在尋找的。有沒有選項可以將一個大文件壓縮成更小的塊? - JohnG


 可以在不安裝任何附加文件的情​​況下壓縮文件 軟件(我已經測試過了)。解決方案是:

在命令行窗口中運行此命令以創建zip文件 命名 C:\someArchive.zip 包含文件夾中的所有文件 C:\test3

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

哪裡有檔案 zip.vbs 包含:

'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

我沒有測試它包含空格的路徑和文件名。如果引用它可能會有效 放在命令行參數周圍。


工作原理:Windows中的內置zip功能(Windows XP及更高版本?)是 透過 COM 來自Windows shell的接口 ,explorer.exe - 這是“Shell.Application”的一部分。這個COM接口可以從a使用 VBScript中 腳本因為 這樣的腳本可以訪問COM組件。為了使腳本完全自包含,它創建 要啟動的空ZIP文件(還可以創建一個空的ZIP文件,並將其與VBScript腳本一起復製到目標系統)。

默認情況下,每個桌面都安裝了VBScript 自Windows 98以來發布Microsoft Windows。

CScript.exe 是Windows腳本宿主的一部分。 默認情況下,Windows腳本宿主在Windows 98和更高版本的Windows上進行分發和安裝。如果安裝了Internet Explorer 5(或更高版本),也會安裝它。


35
2018-02-20 15:48



+1良好的解決方案,將“剛剛運行”,但我選擇BAT是出於其他幾個未列出的原因。所以我更喜歡BAT解決方案。 - Aaron Bush
@Aaron Bush:這個腳本和Beaner都提供了一個命令,可以根據請求使用windows內置函數在命令行上壓縮文件。 您可以像任何其他命令一樣將該命令添加到批處理文件中。 - quack quixote
請注意,傳入的路徑必須是絕對路徑,而不是相對路徑。我還必須在這裡使用答案中的技巧: stackoverflow.com/q/1645843/99640 - Chuck Wilbur
路徑必須是絕對的,它似乎隨機失敗:( - kixorz
應該選擇這個作為答案。 - The Duke Of Marshall שלום


如果您願意使用 電源外殼,zip功能在.NET 2.0中可用(PowerShell是.NET)。這是一個例子(資源感謝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)}

11
2018-02-19 21:59



這與其他答案中的CScript代碼基本相同。沒有使用.NET功能(並且.NET無論如何都沒有ZIP支持)。我懷疑這也可能對時間問題很敏感。 - Robert Schmidt
版本4.5中添加了.NET System.IO.Compression.ZipFile類。 - Concrete Gannet


通過輪詢壓縮對話框窗口的存在,可以消除壓縮期間超時的風險。此方法還處理用戶取消壓縮窗口。

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

7
2017-11-23 00:47



+1。那些代碼猴子風格“.Sleep(whatever)“ 讓我感到不舒服。 - ivan_pozdeev
如果我正在運行具有上述邏輯的vbs進行等待,如果通過計劃任務(沒有用戶實際登錄)啟動,將如何處理。 - Wes


如果你能夠安裝 資源工具包工具,你會發現一個名為COMPRESS的命令行工具,可以創建像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.

4
2018-02-19 20:29



+1並不能真正解決問題,但仍然可以很好地了解。 - Aaron Bush


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

3
2017-08-07 07:46



正是我在尋找...但它確實給我一個錯誤“缺少空Zip文件” - Sonic Soul
出於某種原因,如果我打印,這永遠不會增加 objShell.NameSpace( ZipFile ).Items.Count 在循環內部,即使創建了zip文件並且內部具有預期內容,它始終為0 ... - Thom Nichols


具有簡化代碼的多個文件/目錄。

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

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
2017-11-05 21:06





這是已接受答案的變異。我一次對多達數千個文件執行大量自動化任務,因此我不能只睡2秒而不關心它。我收集了解決方法 這裡,這也與JiříKočara的回答類似 這裡

這將導致目標文件夾每200ms被ping一次,這大約與微軟檢查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
2018-06-07 21:53





這是我嘗試總結壓縮和解壓縮的內置功能窗口 - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders-with-batch-f

一些給定的解決方案應該適用於幾乎所有的Windows機器。

至於 shell.application 和WSH我更喜歡 JScript中 因為它允許混合批處理/ jscript文件(擴展名為.bat)不需要臨時文件。我已經將解壓縮和zip功能放在一個文件中,再加上一些功能。


1
2018-01-22 12:31