如何使用仅限于Windows内置功能的脚本进行压缩或解压缩?

325

在Windows中,您可以通过以下方式压缩一些文件:

右键单击 → 发送到压缩 (zipped) 文件夹

并且通过双击 .zip 文件来解压缩并提取文件。

有没有一种方法可以通过脚本(.bat 文件)来应用这些功能而不需要安装任何第三方软件


1
线索在这里:https://dev59.com/0HVD5IYBdhLWcg3wR5go和https://dev59.com/Y3NA5IYBdhLWcg3wS7wm请注意,这是英译中的翻译。 - doctorlove
请使用7zip https://sevenzip.osdn.jp/chm/cmdline/syntax.htm。 - The Student
这个问题在2010年已经在Super User上得到了清晰的回答,比现在早了2年半。 - Peter Mortensen
18个回答

191

为了进一步扩展Steven Penny的PowerShell解决方案,您可以通过像这样调用powershell.exe将其合并到批处理文件中:

要扩展Steven Penny的PowerShell解决方案,您可以通过像这样调用powershell.exe将其合并到批处理文件中:

powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', 'bar'); }"

正如Ivan Shilo所说,这无法在PowerShell 2中工作,需要PowerShell 3或更高版本和.NET Framework 4。


1
实际上,这是在.NET 4.5中提供的。 - qJake
11
对于那些像我一样想知道如何将文件解压到当前目录(而不是创建一个新的目录)的人,只需将目标参数设置为“'.'”,例如:powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', '.'); }"。请注意,这不会改变原来的意思。 - Munchkin
1
& {} 的目的是什么?在 PS5 中,这也可以工作:powershell.exe -nologo -noprofile -command "Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', '.');" - Roi Danton

149
如果您安装了Java,可以使用jar命令将文件压缩为ZIP存档文件:
jar -cMf targetArchive.zip sourceDirectory

c = 创建一个新的压缩文件。

M = 指定不将清单文件添加到压缩文件中。

f = 表示目标文件名。


3
太棒了,谢谢,这正是我在寻找的东西...顺便提一下,我不得不在DOS中删除减号...例如,jar cMf target.zip sourceDir - mlo55
5
还不错,但你需要安装JDK,而不是JRE。 - pdem
8
这是否被 “仅仅使用Windows内置功能” 所覆盖?(我强调了“仅仅”和“内置”) - Peter Mortensen
另外,我们可以在bash中设置“alias zip ='jar -cMf'”,以便不必记住“jar”参数。 - kittu

100

PowerShell 5.0

您可以使用Microsoft.PowerShell.Archive 中的以下命令:

例如:

  • 创建来自整个Test文件夹的result.zip:

Compress-Archive -Path C:\Test -DestinationPath C:\result
  • result.zip 的内容提取到指定的 Test 文件夹中:

  • Expand-Archive -Path result.zip -DestinationPath C:\Test
    

    16
    非常好,谢谢。对于任何跟着到这里的人,你可以在命令行中直接使用powershell Compress-Archive -Path C:\SomeFile.ext -DestinationPath C:\SomeFile.zip而无需制作脚本(假设你安装了Powershell v5,至少可以适用于Windows 7)。 - Beems
    1
    运行良好,如果您计划重新运行它,请添加-Force选项。 - Robin Salih
    1
    @Beems,谢谢你!但我认为你把路径/目标搞反了? - Yiping
    1
    这个可以工作,但是归档文件的压缩方式与使用Windows资源管理器“发送到->压缩(zipped)文件夹”时不同。PowerShell版本较大,有些程序无法提取。 - Eric Labashosky
    Compress-Archive 对输入文件的最大文件限制为2GB。 - Sergei Rodionov
    我也注意到了与@Eric类似的问题。压缩文件与使用“发送到->压缩(zipped)文件夹”创建的文件不同。 - Gangula

    87

    1
    这是不正确的,因为PS允许这样做,并且预装在Windows上,并可通过命令行使用。 - Dan Atkinson
    @DanAtkinson 那你回答了错误的问题;问题要求提供一种“从命令行应用这些能力”的方法。 - Michael Mrozek
    6
    @MichaelMrozek,“命令行”是通称,不仅指CMD/COMMAND,PS绝对也是命令行,*nix上的bash、sh、rsh也都是。更进一步说,既然可以从命令行运行PowerShell,即使你认为cmd/command是唯一的命令行,它也能回答问题。 - Robert McKee
    2
    自2013年起(无需安装任何额外软件)就有可能实现。请参阅超级用户问题。自2001年Windows XP发布以来,这已经成为了可能。可以利用在Windows XP中内置的ZIP功能,因为它是通过COM接口公开的。 - Peter Mortensen

    37

    虽然不是ZIP格式,但使用Windows工具压缩文件的唯一方法是:

    makecab <source> <dest>.cab
    

    解压缩:

    expand <source>.cab <dest>
    

    高级示例(来自ss64.com):

    Create a self extracting archive containing movie.mov:
    C:\> makecab movie.mov "temp.cab"
    C:\> copy /b "%windir%\system32\extrac32.exe"+"temp.cab" "movie.exe"
    C:\> del /q /f "temp.cab"
    

    更多信息: makecabexpandmakecab高级用法



    32

    使用7-Zip:

    压缩:您有一个名为foo的文件夹,想将其压缩为myzip.zip

    "C:\Program Files\7-Zip\7z.exe" a  -r myzip.zip -w foo -mem=AES256
    

    解压缩: 您想要将 (myzip.zip) 解压缩到当前目录 (./)。

    "C:\Program Files\7-Zip\7z.exe" x  myzip.zip  -o./ -y -r
    

    36
    请注意问题:“不需要安装任何第三方软件”。 - Roee Gavirel
    1
    @ Roland:通过指定这个开关(-w),您可以设置临时基本存档文件将被构建的工作目录。在构建临时基本存档文件之后,它会被复制到原始存档上;然后,临时文件将被删除。 - Monir
    @Monir明白了。但是为什么?如果没有使用-w开关,临时基本存档将在同一目录中,那么使用-w与不使用该开关相比有什么好处呢? - Roland
    @Roland:是的,您说得对。除非我们想要指定特定的路径,否则我们不会得到任何东西。 - Monir

    8

    您可以使用包装在BAT文件中的VBScript脚本。此代码适用于相对路径。

    不需要任何第三方工具或依赖项。只需设置SOURCEDIROUTPUTZIP

    文件名:ZipUp.bat

    echo Set fso = CreateObject("Scripting.FileSystemObject") > _zipup.vbs
    echo InputFolder = fso.GetAbsolutePathName(WScript.Arguments.Item(0)) >> _zipup.vbs
    echo ZipFile = fso.GetAbsolutePathName(WScript.Arguments.Item(1)) >> _zipup.vbs
    
    ' Create empty ZIP file.
    echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipup.vbs
    
    echo Set objShell = CreateObject("Shell.Application") >> _zipup.vbs
    echo Set source = objShell.NameSpace(InputFolder).Items >> _zipup.vbs
    echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipup.vbs
    
    echo ' Keep script waiting until compression is done
    echo Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count >> _zipup.vbs
    echo     WScript.Sleep 200 >> _zipup.vbs
    echo Loop >> _zipup.vbs
    
    CScript  _zipup.vbs  %SOURCEDIR%  %OUTPUTZIP%
    
    del _zipup.vbs
    

    使用示例

    SET SOURCEDIR=C:\Some\Path
    SET OUTPUTZIP=C:\Archive.zip
    CALL ZipUp
    

    或者您可以通过替换该行 CScript _zipup.vbs %SOURCEDIR% %OUTPUTZIP% 来参数化此文件,使用 CScript _zipup.vbs %1 %2,这样只需调用 CALL ZipUp C:\Source\Dir C:\Archive.zip 即可更轻松地调用它。


    创建初始zip文件的那一行需要进行转义,否则它将不会出现在脚本中。 - cup
    是的,这是正确的方式(就像超级用户问题中所述)。 - Peter Mortensen
    为什么每次使用命令时都要重新编写VBS文件呢? - OMA

    7
    我一直在寻找答案,经过我的研究,DiryBoy的回答似乎是准确的。我发现compact.exe程序可以压缩文件,但不能创建高度压缩的文件(或文件集)。它类似于在Windows中右键单击驱动器字母或分区时获得的选项。您可以选择清理(删除临时文件等)以及压缩文件。压缩后的文件仍然可以访问,但只是被压缩以在低空间的驱动器上创建空间。
    我还发现了compress.exe,我确实在我的电脑上有这个程序。它并不是Windows机器上原生的一部分,而是2003资源工具包的一部分。它确实制作了一种类似于来自Windows安装光盘的文件的压缩文件(文件扩展名或名称的最后一个字符为下划线)。而extract.exe命令则提取这些文件。
    然而,口号是,如果可以通过GUI本地完成,则可能有一种通过批处理、.vbs或其他类型的脚本在命令行中完成的方法。由于Windows已经有“发送到”选项来创建zip文件,我知道必须有一种通过命令行完成的方法,我找到了一些选项。

    这是一个很棒的链接,展示了如何使用Windows原生命令压缩文件。

    https://superuser.com/questions/110991/can-you-zip-a-file-from-the-command-prompt-using-only-windows-built-in-capabili

    我用一个包含多个嵌套文件和文件夹的目录进行了测试,它完美地工作了。只需按照命令行的格式进行操作即可。
    还有一种通过命令行解压缩文件的方法,我也找到了。其中一种方式只是打开一个资源管理器窗口,显示压缩文件的内容。其中一些还使用Java,尽管它不是Windows本地应用程序,但是非常普遍,几乎看起来像是本地应用程序。

    https://superuser.com/questions/149489/does-windows-7-have-unzip-at-the-command-line-installed-by-default

    如何使用命令行解压文件?


    不,DiryBoy的回答是不准确的 - Peter Mortensen

    5

    如果你需要在脚本的一部分中进行此操作,最好的方法是使用Java。假设bin目录在您的路径中(在大多数情况下),您可以使用命令行:

    jar xf test.zip
    

    如果Java不在您的路径上,请直接引用它:

    C:\Java\jdk1.6.0_03\bin>jar xf test.zip
    

    4

    我对所有这些解决方案都有问题。

    它们并不完全相同,并且它们所创建的文件与从同一源文件夹制作的RMB --> 发送到 --> 压缩(zipped)文件夹相比存在轻微的大小差异。我遇到的最接近的大小差异是300 KB(脚本 > 手动),使用以下方法制作:

    powershell Compress-Archive -Path C:\sourceFolder -CompressionLevel Fastest -DestinationPath C:\destinationArchive.zip
    

    (注意 -CompressionLevel. 有三个可能的值: Fastest, NoCompression 和 Optimal (默认值: Optimal))

    我想制作一个批处理文件,可以自动压缩我正在开发中的 WordPress 插件文件夹为 .zip 文件,这样我就可以将其上传到 WordPress 网站并测试插件。

    但是由于某些原因,它无法使用任何自动压缩选项,但是它可以使用手动右键菜单压缩,这让我感到非常奇怪。

    而且脚本生成的 .zip 文件实际上破坏了 WordPress 插件,以至于它们无法被激活,并且也无法从 WordPress 中删除。我必须通过 SSH 进入服务器的“后端”并手动删除上传的插件文件,而手动右键菜单生成的文件则可以正常工作。


    1
    什么是"wbr"和"RMB"? - Peter Mortensen
    RMB代表鼠标右键。 <wbr>是HTML标签,用于向浏览器指示“单词中断机会”(已删除,因为它无效)。 - Sebastian Norr

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接