如何仅使用 Windows 的内置功能从脚本中压缩或解压缩?

Posted

技术标签:

【中文标题】如何仅使用 Windows 的内置功能从脚本中压缩或解压缩?【英文标题】:How can you zip or unzip from the script using ONLY Windows' built-in capabilities? 【发布时间】:2013-07-06 22:18:09 【问题描述】:

在 Windows 中,您可以通过

压缩一些文件

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

双击.zip文件解压并解压文件。

有没有办法通过脚本(.bat 文件)应用这些功能无需安装任何第三方软件

【问题讨论】:

这里的线索:***.com/questions/30211/… 和 ***.com/questions/1021557/… 嗯,可能是为了从批处理文件或程序中调用它。 (这就是我来这里的原因——尝试制作一个快速的 .BAT 文件来为需要它是 zip 文件的网站“构建”一个小产品。) 这个问题被关闭了。 这个问题可以转给超级用户吗? 在 2018 年仍然非常有用和相关。:P 【参考方案1】:

要扩展 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。

【讨论】:

实际上,这是在 .NET 4.5 中提供的。 对于那些(像我一样)想知道如何提取到实际目录(而不是创建新目录)的人,只需将目标参数设置为'.',例如:powershell.exe -nologo -noprofile -command "& Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', '.'); " 我们可以使用这些命令来增加压缩吗?喜欢使其超压缩以减小文件大小? & 的目的是什么?使用 PS5 也可以:powershell.exe -nologo -noprofile -command "Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', '.');" @RoiDanton 如何使用 stringformatter 定义 src.zip 和 dest.zip ?【参考方案2】:

如果您安装了 Java,则可以使用 jar 命令压缩为 ZIP 存档:

jar -cMf targetArchive.zip sourceDirectory

c = 创建一个新的存档文件。

M = 指定不应将清单文件添加到存档中。

f = 表示目标文件名。

【讨论】:

太棒了,谢谢,正是我想要的...仅供参考-我必须删除DOS中的减号...例如jar cMf target.zip sourceDir 不错,但您需要安装 JDK,而不是 JRE。 不错的一个,可能是最独立于平台的解决方案;) YMMD。真棒的想法。节省了我很多时间。 这是否包含在 "... 使用 ONLY Windows 的 内置 功能?"(我的重点)【参考方案3】:

PowerShell 5.0

来自Microsoft.PowerShell.Archive,您可以使用:

Compress-Archive Expand-Archive

例如:

从整个 Test 文件夹创建 result.zip

Compress-Archive -Path C:\Test -DestinationPath C:\result

提取指定Test文件夹中result.zip的内容:

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

【讨论】:

这很好用,谢谢。对于任何在这里结束的人,您可以直接从命令行使用powershell Compress-Archive -Path C:\SomeFile.ext -DestinationPath C:\SomeFile.zip,而无需编写脚本(假设您安装了 Powershell v5,您至少可以回到 Windows 7)。 效果很好,如果您打算重新运行它,请添加 -Force 选项。 @Beems,谢谢!但我认为你反过来把路径/目的地弄疯了? 这行得通,但存档的压缩方式不同,如果您使用 Windows 资源管理器“发送到 -> 压缩(压缩)文件夹”会发生什么情况 Powershell 版本更大,某些程序无法提取 Compress-Archive 对输入文件的最大文件限制为 2GB【参考方案4】:

早在 2013 年,这是不可能的。 Microsoft 没有为此提供任何可执行文件。

有关执行此操作的一些 VBS 方法,请参阅此链接。 https://superuser.com/questions/201371/create-zip-folder-from-the-command-line-windows

从 Windows 8 开始,默认安装 .NET Framework 4.5,提供System.IO.Compression.ZipArchive 和 PowerShell,可以编写脚本来实现这一点,请参阅 https://***.com/a/26843122/71312

【讨论】:

这是不正确的,因为 PS 允许这样做并且预装在 Windows 上并且可以通过命令行使用。 @DanAtkinson 已更新。它在 2013 年得到了回答,该链接提供了一些 VBS 方式。 PS方式需要.Net 4.5,需要Windows 8或以上。 感谢您的更新!相应地修改了我的投票。 :) @MichaelMrozek 好吧,“命令行”泛指任何命令行,而不是具体的 CMD/COMMAND,PS 绝对是命令行,*nix 上的 bash、sh、rsh 也是如此。但更进一步,由于您可以从命令行运行 powershell,即使您想相信 cmd/command 是唯一的命令行,它也确实回答了这个问题。 在 2013 年可能的(无需安装任何额外的软件)。见the Super User question。自从Windows XP 于 2001 年问世以来,这一直是可能的。可以利用 Windows XP 中的内置 ZIP 功能,因为它通过 COM interface 公开。【参考方案5】:

它不完全是 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"

更多信息:makecab、expand、makecab advanced uses

【讨论】:

不,it is not the only way to compress a file using Windows tools。【参考方案6】:

使用 7-Zip:

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

【讨论】:

请注意问题:without the need to install any 3rd party @RoeeGavirel 7zip 应该是您在任何 Windows 安装中首先安装的东西之一:P @developerbmw - A.为什么会这样? B. 我在生产中处理约 100 台没有 7zip 的机器。要安装它,我必须让 DevOps 将它安装在所有这些机器上以及将添加到集群的所有新机器上。我宁愿避免它。 @Roland:你能不能说点儿话;哪里出错了?这将对所有人都有帮助。 @Roland :刚刚检查过,语法运行良好。您可能正在尝试使用您的机器中不存在的文件夹“foo”。只是猜测。【参考方案7】:

您可以使用包装在 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 文件的行需要转义,否则它不会出现在脚本中。 是的,这是要走的路(就像在the Super User question 中一样)。 我添加了一个正确转义的版本作为答案。 为什么每次使用命令都要重写VBS文件?【参考方案8】:

我一直想回答这个确切的问题,根据我的研究,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

How to unzip a file using the command line?

【讨论】:

不,DiryBoy's response is not accurate【参考方案9】:

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

jar xf test.zip

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

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

【讨论】:

【参考方案10】:

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

它们不完全相同相同,并且它们都创建的文件与RMB --&gt; send to --&gt; compressed (zipped) folder 从同一源文件夹创建时的大小略有不同。我所拥有的最接近的大小差异是 300 KB 差异(脚本>手册),使用:

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

(注意 -CompressionLevel。There are three possible values:最快,无压缩和最佳,(默认:最佳))

我想制作一个 .bat 文件,该文件应该自动将我正在处理的 WordPress 插件文件夹压缩到一个 .zip 存档中,这样我就可以将它上传到 WordPress 网站并测试插件。

但由于某种原因,它不适用于任何这些自动压缩,它确实适用于手动 RMB 压缩,我觉得这很奇怪。

脚本生成的 .zip 文件实际上破坏了 WordPress 插件,使其无法激活,也无法从 WordPress 内部删除。我必须通过 SSH 连接到服务器的“后端”并手动删除上传的插件文件。而手动生成的RMB文件正常工作。

【讨论】:

什么是"wbr""RMB" RMB = 鼠标右键。 = 向浏览器指示“Word BReak 机会”的 html 标记(已删除,因为它不起作用)。【参考方案11】:

这是@PodTech.io 提供的答案的更新版本

此版本在批处理文件中正确转义了所有 vbs 代码。 它还被创建到一个子例程中,可以在批处理脚本的任何地方用一行代码调用它:

:: === Main code:

call :ZipUp "C:\Some\Path" "C:\Archive.zip"


:: === SubRoutines:

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

【讨论】:

【参考方案12】:

您说您尝试在没有第三方软件的情况下执行此操作。我不确定您是否会考虑使用 .NET“第三方”软件。

但是您可以在 .NET 中创建自己的命令行实用程序。它不应该需要超过几行代码。

ZipFile Class

【讨论】:

【参考方案13】:

开源是你的朋友:-)

这里是解压:http://gnuwin32.sourceforge.net/packages/unzip.htm

还有一个 ZIP 命令: http://gnuwin32.sourceforge.net/packages/zip.htm

二进制文件下载就足够了。

【讨论】:

在 Windows 8 上,它会抛出错误:bzip2.dll is missing. @Doug 它说 bzip2 是页面上的要求,并且有一个下载链接 最初的问题是如何使用标准的内置 Windows 命令。此外,要求您的用户安装各种第三方解决方案是不可取的,因为您自己的工具或解决方案现在仅限于对其计算机具有管理权限的用户,或者不关心他们系统上越来越多的小依赖项的用户.开源可能是你的朋友,但是需要你安装其他开源包的开源包,需要你安装其他开源包等等的开源包绝对不是你的朋友。 SourceForge 被我工作的防火墙策略阻止 :-( 这仍然使用第三方软件【参考方案14】:

较新的 Windows 版本包括 tar.exe。 tar.exe 可以在 cmd 或 windows 批处理文件中使用。

//Compress a folder:
tar -caf aa.zip c:\aa

【讨论】:

【参考方案15】:

Shell.Application

使用 Shell.Application,您可以模拟 explorer.exe 压缩文件和文件夹的方式 该脚本名为zipjs.bat:

:: unzip content of a zip to given folder.content of the zip will be not preserved (-keep no).Destination will be not overwritten (-force no)
call zipjs.bat unzip -source C:\myDir\myZip.zip -destination C:\MyDir -keep no -force no

:: lists content of a zip file and full paths will be printed (-flat yes)
call zipjs.bat list -source C:\myZip.zip\inZipDir -flat yes

:: lists content of a zip file and the content will be list as a tree (-flat no)
call zipjs.bat list -source C:\myZip.zip -flat no

:: prints uncompressed size in bytes
zipjs.bat getSize -source C:\myZip.zip

:: zips content of folder without the folder itself
call zipjs.bat zipDirItems -source C:\myDir\ -destination C:\MyZip.zip -keep yes -force no

:: zips file or a folder (with the folder itslelf)
call zipjs.bat zipItem -source C:\myDir\myFile.txt -destination C:\MyZip.zip -keep yes -force no

:: unzips only part of the zip with given path inside
call zipjs.bat unZipItem -source C:\myDir\myZip.zip\InzipDir\InzipFile -destination C:\OtherDir -keep no -force yes
call zipjs.bat unZipItem -source C:\myDir\myZip.zip\InzipDir -destination C:\OtherDir 

:: adds content to a zip file
call zipjs.bat addToZip -source C:\some_file -destination C:\myDir\myZip.zip\InzipDir -keep no
call zipjs.bat addToZip -source  C:\some_file -destination C:\myDir\myZip.zip

MAKECAB

Makecab 是 windows 自带的默认压缩工具。虽然它可以使用不同的压缩算法(包括 zip),但文件格式始终是 .cab 文件。通过一些扩展,它也可以在 linux 机器上使用。

压缩文件:

makecab file.txt "file.cab"

压缩整个文件夹需要更多的工作。这里一个目录是用cabDir.bat压缩的:

call cabDir.bat ./myDir compressedDir.cab

使用expand 命令解压缩相当容易:

EXPAND cabfile -F:* .

更骇人听闻的方法是使用 extrac32 命令创建自解压可执行文件:

copy /b "%windir%\system32\extrac32.exe"+"mycab.cab" "expandable.exe"
call expandable.exe

焦油

在 windows 的 build 17063 中,我们有 tar 命令:

::compress directory
tar -cvf archive.tar c:\my_dir
::extract to dir
tar -xvf archive.tar.gz -C c:\data

.NET 工具

.net(和 powershell)提供了许多压缩和解压缩文件的方法。最直接的是使用 gzip 流。该脚本名为gzipjs.bat:

::zip
call gzipjs.bat -c my.file my.zip
::unzip
call gzipjs.bat -u my.zip my.file

【讨论】:

【参考方案16】:

加上@Jason Duffett 的answer 及其cmets,下面是一个获取用户输入和输出(分别为文件名和目录名)的脚本:

@echo off
set input=%1
set output=%2
powershell.exe "Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('%input%', '%output%');"

用法:

unzip.bat path\to\file.zip path\to\output\directory

【讨论】:

批处理文件方法的 PowerShell 有两个小问题: 1. 过程中没有文本输出来查看正在提取的内容的进度。 2. 进程不能被Ctrl+C 或任何其他组合键中断。只有从任务管理器中杀死“powershell.exe”进程才会停止它。【参考方案17】:

这个对我有用(2021 年):

tar -xf test.zip

这将解压当前目录中的test

【讨论】:

【参考方案18】:

我找到了一种用批处理文件解压缩 zip 文件的方法:

@echo off
::unziper
set /p zip=zip:
powershell -Command "Expand-Archive %zip%"
echo done
pause

如果有人需要,我会发布这个。 为什么要编辑我的答案?

【讨论】:

【参考方案19】:

正如@Noam Manos 所回答的,我们可以通过在.bashrc file 中使用别名来进一步改进压缩:

alias zip='jar -cMf'

然后命令(在 bash 终端中)将是

zip target.zip dir1 dir2

注意:您应该在 windows 中安装并设置 java 和 git bash 才能正常工作。

【讨论】:

谢谢,但正如问题所述:without the need to install any third-party software。所以如果我需要安装 Java 和 GitBash,我只需要安装 ZIP。 @RoeeGavirel 我知道,但现在大多数开发环境都有 java 和 git,所以它对别名有帮助:) 我想,我最初问的问题(8 年前)是当我们在全球范围内拥有多个带有物理实例的数据中心时(在云之前),因此需要我们安装新软件在大约 100 台机器上手动安装它,这是我试图避免的。

以上是关于如何仅使用 Windows 的内置功能从脚本中压缩或解压缩?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 flyway 中压缩/合并迁移

如何在Mac中压缩文件

如何zstd从输入文件中压缩一大块字节?

如何使用 Java 在 SFTP 或 FTP 服务器中压缩文件?

sh js在bash脚本中压缩

如何从流/渲染字典中压缩 html 文件?