Windows的内置ZIP压缩可以编写脚本吗?
Windows XP / Vista / 2003/2008内置的ZIP压缩是否可以完全编写脚本?我必须从BAT / CMD文件中调用什么可执行文件?还是可以用VBScript做到这一点?
我意识到使用WinZip,7-Zip和其他外部应用程序可以实现此目的,但是我正在寻找不需要安装任何外部应用程序的东西。
解决方案
回答
SourceForge(http://sourceforge.net/projects/unxutils)上的UnxUtils包中同时包含zip和unzip可执行文件(以及其他有用的应用程序)。将它们复制到PATH中的某个位置,例如" c:\ windows",我们便可以将它们包括在脚本中。
这不是完美的解决方案(或者我们要求的解决方案),而是一个不错的解决方案。
回答
也有VBA方法也可以使用内置的压缩窗口来压缩和解压缩,这应该使我们对系统的运行方式有一些了解。我们可能可以将这些方法构建为我们选择的脚本语言。
基本原则是,在Windows中,我们可以将zip文件视为目录,然后将其复制到目录中或者从目录中复制出来。因此,要创建一个新的zip文件,我们只需简单地创建一个扩展名为.zip的文件,该文件的正确标题就应该是一个空zip文件。然后关闭它,并告诉Windows我们要将文件复制到其中,就好像它是另一个目录一样。
解压缩更容易,只需将其视为目录即可。
如果网页再次丢失,这里是一些相关的代码片段:
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
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
回答
是的,可以使用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
我们可能还会发现http://www.naterice.com/blog/template_permalink.asp?id=64很有帮助,因为它包括VBScript中完整的Unzip / Zip实现。
如果我们每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
非常适合大量的日志文件。
回答
只是为了清楚起见:GZip不是Guy Starbuck在8月发表的评论中建议的仅MS算法。
System.IO.Compression中的GZipStream使用Deflate算法(与zlib库相同)和许多其他zip工具。该类可与gzip之类的unix实用程序完全互操作。
不能从命令行或者VBScript编写GZipStream类来生成ZIP文件,因此仅凭它不能解决原始发布者的请求。
免费的DotNetZip库可以读取并生成zip文件,并且可以从VBScript或者Powershell编写脚本。它还包括用于生成和读取/提取zip文件的命令行工具。
这是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.")
这是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");
在.bat或者.cmd文件中,可以使用zipit.exe或者unzip.exe工具。例如:
zipit NewZip.zip -s "This is string content for an entry" Readme.txt src