您能否仅使用Windows的内置功能从命令提示符中压缩文件?


111

我有一个输出文本文件的批处理文件。我认为如果也可以将其拉上拉链会很好。

这将在不受控制的环境中使用,因此我无法对第三方软件产品(例如7-Zip等)的存在做出假设。这需要使用Windows现在内置的功能来压缩文件。


1
您可以利用Powershell或WSH脚本吗?这可能是从命令行使用Windows内置zip处理的唯一方法。否则,正如Molly指出的那样,您需要一个第三方工具。
quack quixote 2010年

1
因此您向某人发送了一个批处理文件,而您却无法向他发送一些微小的静态链接的gzip.exe?
akira 2010年

OP的问题非常棒(尽管@quackquixote提出了奇怪的指控)。由于Windows确实是在SendTo下单击提供的,因此在BAT文件中应该有一个可用的命令。因此,即使答案为“否”并且必须(荒唐地)诉诸使用可能等效或不等效的第三方工具,这也是一个好问题。
乔恩·库姆斯

这是Tomas的链接,具有写得很好的脚本来压缩文件夹的内容。要使其工作,只需将脚本复制到批处理文件中,然后通过指定要压缩的文件夹(源)执行该脚本即可。无需提及目标目录,因为该目录在脚本中默认为桌面(“%USERPROFILE%\ Desktop”)
Abhijeet

3
最简单的方法是在cmd提示符下:(powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip它也适用于文件夹)
ThomasGuenet

Answers:


85

这是一个全批处理文件解决方案(是我其他回答的一个变体),它将压缩名为的文件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。因为通常不必TEMPDIR更改驱动器C的根目录。

.bat脚本所在的文件夹也需要写访问权限(因为脚本会在其中生成文件)。

另外,请注意,压缩文件的文件扩展名必须为.zip。尝试使用其他扩展名可能会导致脚本错误。而是,生成.zip文件并重命名。


3
@quack我一直在坚持,希望能得到一些我不知道的晦涩命令。我可以看到,如果不存在一个困难的要求,那并不意味着要把任何人赶出去,您会如何发现它。
亚伦·布什

@PeterMortensen:看看用Powershell可以简化多少可能有趣。这是一个5行示例,但是也存在一个write-zip可以从Pscx下载的cmdlet
Tamara Wijsman

我使用zip.exe和cywin1.dll(3mb)来满足ZIP的需要,用法仅一行...从使用某些批处理代码的zip本身开始。我知道可以使用argv banphp编译的php并将文件传递给它。听起来不错。“ Windows命令行中的zip”是一部古老的科幻电影,对不对?
erm3nda 2013年

为什么我们必须使用一个临时文件夹TEMPDIR?我认为您的意图是FILETOZIP通过文件夹包装文件,对吗?
Nam G VU 2014年

@Peter Mortensen,我知道这是一个老话题,这几乎是我想要的。是否可以将一个大文件压缩为较小的块?
JohnG '16

38

可能的zip文件,无需安装任何额外的软件(我测试)。解决方案是:

在命令行窗口中运行此命令,以创建一个名为ZIP文件,该文件C:\someArchive.zip包含folder中的所有文件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 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

我尚未针对包含空格的路径和文件名对其进行测试。如果在命令行参数两边加上引号,则可能会起作用。


它是如何工作的:Windows(Windows XP和更高版本?)中的内置zip功能是通过Windows外壳explorer.exe的COM接口公开的,它是“ Shell.Application”部分。可以从VBScript脚本使用此COM接口,因为这样的脚本可以访问COM组件。为了使脚本完全独立,它会创建一个空的ZIP文件来开始使用(也可以创建一个空的ZIP文件并将其与VBScript脚本一起复制到目标系统中)。

自Windows 98以来,默认情况下已在Microsoft Windows的每个桌面版本中安装VBScript。

CScript.exeWindows Script Host的一部分。默认情况下,Windows Script Host已分发并安装在Windows 98和更高版本的Windows上。如果安装了Internet Explorer 5(或更高版本),则也将安装它。


1
+1好的解决方案将“运行”,但出于其他一些未列出的原因,我选择了BAT。所以我更喜欢BAT解决方案。
亚伦·布什

4
@Aaron Bush:此脚本和Beaner都提供了一个命令,该命令可根据要求使用Windows内置函数在命令行上压缩文件。 您可以像其他命令一样将该命令添加到批处理文件中。
quack quixote

请注意,传入的路径必须是绝对路径,而不是相对路径。我还必须在这里使用答案中的技术:stackoverflow.com/q/1645843/99640
Chuck Wilbur 2012年

路径必须是绝对的,并且似乎随机失效:(
kixorz 2014年

应该选择它作为答案。
马歇尔公爵שלום14年

12

如果您愿意使用PowerShell,则可以在.NET 2.0中使用zip功能(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)}

这与其他答案中的CScript代码基本相同。不使用.NET功能(而且.NET始终不支持ZIP)。我怀疑这可能对计时问题也很敏感。
罗伯·施密特

2
.NET System.IO.Compression.ZipFile类在版本4.5中添加。
混凝土塘鹅

7

您可以通过轮询压缩对话框窗口的存在来消除压缩期间超时的风险。此方法还可以处理用户取消压缩窗口的操作。

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。那些猴子风格的代码.Sleep(whatever)使我恶心。
ivan_pozdeev 2013年

1
如果我使用上述逻辑运行vbs进行等待,如果通过计划任务(没有用户实际登录的话)启动该vbs,将如何处理
Wes 2013年

5

如果能够安装Resource Kit Tools,则将找到一个名为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.

3
+1并不能真正解决问题,但还是很了解。
亚伦·布什

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

正是我想要的..但​​是它确实给了我一个错误“缺少空Zip文件”
Sonic Soul 2014年

出于某种原因,它永远不会增加,如果我objShell.NameSpace( ZipFile ).Items.Count在循环中打印,即使创建了zip文件并且其中包含预期的内容,它也始终为0 ...
Thom Nichols 2015年

2

具有简化代码的多个文件/目录。

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

这是已接受答案的变异。我一次要对多达数千个文件执行大量自动化任务,因此我不能只睡2秒钟,也不在乎它。我在这里收集了解决方法,这也类似于JiříKočara 在这里的回答。

这将导致每200毫秒对目标文件夹执行一次ping操作,这大约与Microsoft检查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

Here'a我试图总结为压缩和解压缩内置功能窗口- https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders -与批处理-f

给出的解决方案几乎可以在所有Windows机器上使用。

至于shell.application和WSH,我更喜欢jscript, 因为它允许不需要临时文件的混合批处理/ jscript文件(扩展名为.bat)。我已经将unzip和zip功能放在一个文件中,并提供了更多功能。 。


0

如果在Windows 8或Windows Server 2012上,您将拥有PowerShell和.NET 4.5,则可以执行以下操作:

zip.ps1(用法:)-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(如果需要帮助者为您调用PowerShell,则目录为第一个参数,邮政编码为第二个):

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

0

Windows 10内部版本17063或更高版本与tar.exe捆绑在一起,后者可以从命令行使用zip。

tar.exe -xf archive.zip

或创建档案

tar.exe -cf Test.zip Test

-5

现在,Windows命令行提供了紧凑命令,据我所知,该命令是Windows固有的。除非我没有错过任何东西,否则应该可以满足要求。


9
compactXP以来一直存在,并且是管理NTFS压缩的工具
Der Hochstapler 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.