Можно ли запрограммировать встроенное в Windows сжатие ZIP?
-
09-06-2019 - |
Вопрос
Можно ли вообще использовать скрипты для сжатия ZIP, встроенного в Windows XP/Vista/2003/2008?Какой исполняемый файл мне придется вызывать из файла BAT/CMD?или можно ли это сделать с помощью VBScript?
Я понимаю, что это возможно, используя WinZip, 7-Zip и другие внешние приложения, но я ищу что-то, что не требует установки внешних приложений.
Решение
Существуют методы 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 полезен, поскольку включает полную реализацию Unzip/Zip в VBScript.
Если вы выполняете проверку размера каждые 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 не является алгоритмом только для MS, как предложил Гай Старбак в своем комментарии от августа.GZipStream в System.IO.Compression использует алгоритм Deflate, такой же, как библиотека zlib и многие другие инструменты zip.Этот класс полностью совместим с утилитами Unix, такими как gzip.
Класс GZipStream не поддерживает сценарии из командной строки или VBScript для создания ZIP-файлов, поэтому сам по себе он не будет ответом на исходный запрос автора.
Свобода ДотНетЗип библиотека читает и создает 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
Вот моя попытка обобщить встроенные возможности Windows по сжатию и распаковке - Как я могу сжимать (/zip) и распаковывать (/unzip) файлы и папки с помощью пакетного файла без использования каких-либо внешних инструментов?
с несколькими решениями, которые должны работать практически на каждой машине с Windows.
Что касается оболочка.приложение и WSH я предпочел jscriptпоскольку он позволяет создавать гибридные пакетные файлы/файлы jscript (с расширением .bat), для которых не требуются временные файлы. Я поместил возможности распаковки и архивирования в один файл, а также еще несколько функций.
В пакете UnxUtils, доступном на SourceForge, есть исполняемые файлы zip и unzip (а также множество других полезных приложений) (http://sourceforge.net/projects/unxutils).Скопируйте их в папку PATH, например «c:\windows», и вы сможете включать их в свои сценарии.
Это не идеальное решение (или то, о котором вы просили), но достойная работа.
для создания сжатого архива можно использовать утилиту MAKECAB.EXE