Windows 的内置 ZIP 压缩可以编写脚本吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can Windows' built-in ZIP compression be scripted?
提问by travis
Is the ZIP compression that is built into Windows XP/Vista/2003/2008 able to be scripted at all? What executable would I have to call from a BAT/CMD file? or is it possible to do it with VBScript?
Windows XP/Vista/2003/2008 中内置的 ZIP 压缩完全可以编写脚本吗?我必须从 BAT/CMD 文件调用什么可执行文件?或者可以用VBScript来做吗?
I realize that this is possible using WinZip, 7-Zipand other external applications, but I'm looking for something that requires no external applications to be installed.
采纳答案by Adam Davis
There are VBA methods to zipand unzipusing the windows built in compression as well, which should give some insight as to how the system operates. You may be able to build these methods into a scripting language of your choice.
有VBA的方法来压缩和解压使用内置的压缩以及窗户,这应该给一些有识之士为系统如何运作的。您可以将这些方法构建到您选择的脚本语言中。
The basic principle is that within windows you can treat a zip file as a directory, and copy into and out of it. So to create a new zip file, you simply make a file with the extension .zip
that has the right header for an empty zip file. Then you close it, and tell windows you want to copy files into it as though it were another directory.
基本原则是,在 Windows 中,您可以将 zip 文件视为一个目录,并可以将其复制到其中或从中复制出来。因此,要创建一个新的 zip 文件,您只需创建一个.zip
具有空 zip 文件正确标头的扩展名的文件。然后关闭它,并告诉 windows 您要将文件复制到其中,就好像它是另一个目录一样。
Unzipping is easier - just treat it as a directory.
解压缩更容易 - 只需将其视为目录即可。
In case the web pages are lost again, here are a few of the relevant code snippets:
万一网页再次丢失,这里有一些相关的代码片段:
ZIP
压缩
Sub NewZip(sPath)
'Create empty Zip File
'Changed by keepITcool Dec-12-2005
If Len(Dir(sPath)) > 0 Then Kill sPath
Open sPath For Output As #1
Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
Close #1
End Sub
Function bIsBookOpen(ByRef szBookName As String) As Boolean
' Rob Bovey
On Error Resume Next
bIsBookOpen = Not (Application.Workbooks(szBookName) Is Nothing)
End Function
Function Split97(sStr As Variant, sdelim As String) As Variant
'Tom Ogilvy
Split97 = Evaluate("{""" & _
Application.Substitute(sStr, sdelim, """,""") & """}")
End Function
Sub Zip_File_Or_Files()
Dim strDate As String, DefPath As String, sFName As String
Dim oApp As Object, iCtr As Long, I As Integer
Dim FName, vArr, FileNameZip
DefPath = Application.DefaultFilePath
If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
strDate = Format(Now, " dd-mmm-yy h-mm-ss")
FileNameZip = DefPath & "MyFilesZip " & strDate & ".zip"
'Browse to the file(s), use the Ctrl key to select more files
FName = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", _
MultiSelect:=True, Title:="Select the files you want to zip")
If IsArray(FName) = False Then
'do nothing
Else
'Create empty Zip File
NewZip (FileNameZip)
Set oApp = CreateObject("Shell.Application")
I = 0
For iCtr = LBound(FName) To UBound(FName)
vArr = Split97(FName(iCtr), "\")
sFName = vArr(UBound(vArr))
If bIsBookOpen(sFName) Then
MsgBox "You can't zip a file that is open!" & vbLf & _
"Please close it and try again: " & FName(iCtr)
Else
'Copy the file to the compressed folder
I = I + 1
oApp.Namespace(FileNameZip).CopyHere FName(iCtr)
'Keep script waiting until Compressing is done
On Error Resume Next
Do Until oApp.Namespace(FileNameZip).items.Count = I
Application.Wait (Now + TimeValue("0:00:01"))
Loop
On Error GoTo 0
End If
Next iCtr
MsgBox "You find the zipfile here: " & FileNameZip
End If
End Sub
UNZIP
解压缩
Sub Unzip1()
Dim FSO As Object
Dim oApp As Object
Dim Fname As Variant
Dim FileNameFolder As Variant
Dim DefPath As String
Dim strDate As String
Fname = Application.GetOpenFilename(filefilter:="Zip Files (*.zip), *.zip", _
MultiSelect:=False)
If Fname = False Then
'Do nothing
Else
'Root folder for the new folder.
'You can also use DefPath = "C:\Users\Ron\test\"
DefPath = Application.DefaultFilePath
If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
'Create the folder name
strDate = Format(Now, " dd-mm-yy h-mm-ss")
FileNameFolder = DefPath & "MyUnzipFolder " & strDate & "\"
'Make the normal folder in DefPath
MkDir FileNameFolder
'Extract the files into the newly created folder
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(Fname).items
'If you want to extract only one file you can use this:
'oApp.Namespace(FileNameFolder).CopyHere _
'oApp.Namespace(Fname).items.Item("test.txt")
MsgBox "You find the files here: " & FileNameFolder
On Error Resume Next
Set FSO = CreateObject("scripting.filesystemobject")
FSO.deletefolder Environ("Temp") & "\Temporary Directory*", True
End If
End Sub
回答by Jay
Yes, this can be scripted with VBScript. For example the following code can create a zip from a directory:
是的,这可以用 VBScript 编写脚本。例如,以下代码可以从目录创建 zip:
Dim fso, winShell, MyTarget, MySource, file
Set fso = CreateObject("Scripting.FileSystemObject")
Set winShell = createObject("shell.application")
MyTarget = Wscript.Arguments.Item(0)
MySource = Wscript.Arguments.Item(1)
Wscript.Echo "Adding " & MySource & " to " & MyTarget
'create a new clean zip archive
Set file = fso.CreateTextFile(MyTarget, True)
file.write("PK" & chr(5) & chr(6) & string(18,chr(0)))
file.close
winShell.NameSpace(MyTarget).CopyHere winShell.NameSpace(MySource).Items
do until winShell.namespace(MyTarget).items.count = winShell.namespace(MySource).items.count
wscript.sleep 1000
loop
Set winShell = Nothing
Set fso = Nothing
You may also find http://www.naterice.com/blog/template_permalink.asp?id=64helpful as it includes a full Unzip/Zip implementation in VBScript.
您可能还会发现http://www.naterice.com/blog/template_permalink.asp?id=64很有帮助,因为它在 VBScript 中包含了完整的 Unzip/Zip 实现。
If you do a size check every 500 ms rather than a item count it works better for large files. Win 7 writes the file instantly although it's not finished compressing:
如果您每 500 毫秒进行一次大小检查而不是项目计数,则它对大文件效果更好。Win 7 会立即写入文件,但尚未完成压缩:
set fso=createobject("scripting.filesystemobject")
Set h=fso.getFile(DestZip)
do
wscript.sleep 500
max = h.size
loop while h.size > max
Works great for huge amounts of log files.
适用于大量日志文件。
回答by Cheeso
Just for clarity: GZip is not an MS-only algorithm as suggested by Guy Starbuck in his comment from August. The GZipStream in System.IO.Compression uses the Deflate algorithm, just the same as the zlib library, and many other zip tools. That class is fully interoperable with unix utilities like gzip.
只是为了清楚起见:GZip 并不是 Guy Starbuck 在 8 月份的评论中建议的仅限 MS 的算法。System.IO.Compression 中的 GZipStream 使用 Deflate 算法,与 zlib 库和许多其他 zip 工具相同。该类可以与 gzip 等 unix 实用程序完全互操作。
The GZipStream class is not scriptable from the commandline or VBScript, to produce ZIP files, so it alone would not be an answer the original poster's request.
GZipStream 类不能从命令行或 VBScript 编写脚本来生成 ZIP 文件,因此它本身不能回答原始发布者的请求。
The free DotNetZiplibrary does read and produce zip files, and can be scripted from VBScript or Powershell. It also includes command-line tools to produce and read/extract zip files.
免费的DotNetZip库可以读取和生成 zip 文件,并且可以从 VBScript 或 Powershell 编写脚本。它还包括用于生成和读取/提取 zip 文件的命令行工具。
Here's some code for VBScript:
这是 VBScript 的一些代码:
dim filename
filename = "C:\temp\ZipFile-created-from-VBScript.zip"
WScript.echo("Instantiating a ZipFile object...")
dim zip
set zip = CreateObject("Ionic.Zip.ZipFile")
WScript.echo("using AES256 encryption...")
zip.Encryption = 3
WScript.echo("setting the password...")
zip.Password = "Very.Secret.Password!"
WScript.echo("adding a selection of files...")
zip.AddSelectedFiles("*.js")
zip.AddSelectedFiles("*.vbs")
WScript.echo("setting the save name...")
zip.Name = filename
WScript.echo("Saving...")
zip.Save()
WScript.echo("Disposing...")
zip.Dispose()
WScript.echo("Done.")
Here's some code for Powershell:
这是Powershell的一些代码:
[System.Reflection.Assembly]::LoadFrom("c:\dinoch\bin\Ionic.Zip.dll");
$directoryToZip = "c:\temp";
$zipfile = new-object Ionic.Zip.ZipFile;
$e= $zipfile.AddEntry("Readme.txt", "This is a zipfile created from within powershell.")
$e= $zipfile.AddDirectory($directoryToZip, "home")
$zipfile.Save("ZipFiles.ps1.out.zip");
In a .bat or .cmd file, you can use the zipit.exe or unzip.exe tools. Eg:
在 .bat 或 .cmd 文件中,您可以使用 zipit.exe 或 unzip.exe 工具。例如:
zipit NewZip.zip -s "This is string content for an entry" Readme.txt src
回答by npocmaka
Here'a my attempt to summarize built-in capabilities windows for compression and uncompression - How can I compress (/ zip ) and uncompress (/ unzip ) files and folders with batch file without using any external tools?
这是我总结用于压缩和解压缩的内置功能窗口的尝试 -如何在不使用任何外部工具的情况下使用批处理文件压缩 (/ zip )和解压缩 (/ unzip ) 文件和文件夹?
with a few given solutions that should work on almost every windows machine.
一些给定的解决方案应该适用于几乎每台 Windows 机器。
As regards to the shell.applicationand WSH I preferred the jscriptas it allows a hybrid batch/jscript file (with .bat extension) that not require temp files.I've put unzip and zip capabilities in one file plus a few more features.
至于shell.application和 WSH,我更喜欢jscript,因为它允许不需要临时文件的混合批处理/jscript 文件(带有 .bat 扩展名)。我已将解压缩和压缩功能放在一个文件中,并添加了一些其他功能.
回答by brian newman
There are both zip and unzip executables (as well as a boat load of other useful applications) in the UnxUtils package available on SourceForge (http://sourceforge.net/projects/unxutils). Copy them to a location in your PATH, such as 'c:\windows', and you will be able to include them in your scripts.
SourceForge ( http://sourceforge.net/projects/unxutils)上提供的 UnxUtils 包中有 zip 和 unzip 可执行文件(以及大量其他有用的应用程序)。将它们复制到 PATH 中的某个位置,例如“c:\windows”,然后您就可以将它们包含在脚本中。
This is not the perfect solution (or the one you asked for) but a decent work-a-round.
这不是完美的解决方案(或您要求的解决方案),而是一个体面的工作。
回答by lupok
to create a compressed archive you can use the utility MAKECAB.EXE
要创建压缩档案,您可以使用实用程序 MAKECAB.EXE