Czy wbudowana kompresja ZIP systemu Windows może być skryptowana?

Czy kompresja ZIP wbudowana w Windows XP/Vista/2003 / 2008 może być w ogóle skryptowana? Jaki plik wykonywalny musiałbym wywołać z pliku BAT / CMD? czy można to zrobić za pomocą VBScript?

Zdaję sobie sprawę, że jest to możliwe przy użyciu WinZip, 7-Zip i innych zewnętrznych aplikacji, ale szukam czegoś, co nie wymaga instalacji zewnętrznych aplikacji.

Author: Peter Mortensen, 2008-08-27

6 answers

Istnieją metody VBA do zip i rozpakowywania przy użyciu windows wbudowanego w kompresji, jak również, co powinno dać pewien wgląd w to, jak system działa. Możesz być w stanie zbudować te metody w wybranym języku skryptowym.

Podstawową zasadą jest to, że w systemie windows można traktować plik zip jako katalog i kopiować do niego i z niego. Aby utworzyć nowy plik zip, wystarczy utworzyć plik z rozszerzeniem .zip, który ma odpowiedni nagłówek dla pustego plik zip. Następnie zamykasz go i mówisz windows, że chcesz skopiować pliki do niego, tak jakby był to inny katalog.

Rozpakowywanie jest łatwiejsze-traktuj to jak katalog.

W przypadku, gdy strony internetowe zostaną ponownie utracone, oto kilka odpowiednich fragmentów kodu:

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
 33
Author: Adam Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-12 17:01:34

Tak, może to być skryptowane za pomocą VBScript. Na przykład poniższy kod może utworzyć zip z katalogu:

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

Możesz również znaleźć http://www.naterice.com/blog/template_permalink.asp?id=64 pomocne, ponieważ zawiera pełną implementację rozpakowywania / Zip w Vbscripcie.

Jeśli sprawdzasz rozmiar co 500 ms, a nie liczbę pozycji, działa to lepiej dla dużych plików. Win 7 zapisuje plik od razu, mimo że nie został jeszcze skompresowany:

set fso=createobject("scripting.filesystemobject")
Set h=fso.getFile(DestZip)
do
    wscript.sleep 500
    max = h.size
loop while h.size > max 

Działa świetnie dla ogromne ilości plików dziennika.

 27
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-13 08:01:45

Dla jasności: GZip nie jest algorytmem tylko MS, jak zasugerował Guy Starbuck w swoim komentarzu z sierpnia. Strumień gzip w kompresji System. IO. wykorzystuje algorytm Deflate, tak samo jak biblioteka Zlib i wiele innych narzędzi zip. Ta klasa jest w pełni interoperacyjna z narzędziami uniksowymi, takimi jak gzip.

Klasa GZipStream nie jest skryptowalna z wiersza poleceń lub VBScript do tworzenia plików ZIP, więc sama nie byłaby odpowiedzią na żądanie oryginalnego postera.

Wolna biblioteka DotNetZip czyta i tworzy pliki zip i może być skryptowana z VBScript lub Powershell. Zawiera również narzędzia wiersza poleceń do tworzenia i odczytu / rozpakowania plików zip.

Oto jakiś kod do 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.")
Oto kod do 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");

W a .bat lub .plik cmd, możesz użyć zipit.exe lub unzip.narzędzia exe. Eg:

zipit NewZip.zip  -s "This is string content for an entry"  Readme.txt  src 
 5
Author: Cheeso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-25 14:52:44

Oto moja próba podsumowania wbudowanych możliwości windows do kompresji i dekompresji - Jak mogę skompresować (/ zip ) i rozpakować (/rozpakować ) pliki i foldery za pomocą pliku wsadowego bez użycia zewnętrznych narzędzi?

Z kilkoma podanymi rozwiązaniami, które powinny działać na prawie każdej maszynie z windows.

W odniesieniu do powłoki .aplikacji i WSH wolałem jscript ponieważ pozwala na Hybrydowy plik wsadowy / jscript (z .bat extension), że nie wymagaj plików tymczasowych.Umieściłem funkcje rozpakowywania i zip w jednym pliku plus kilka dodatkowych funkcji.

 2
Author: npocmaka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:50

W pakiecie UnxUtils dostępnym na SourceForge (znajdują się zarówno pliki wykonywalne zip, jak i unzip (jak również wiele innych przydatnych aplikacji) http://sourceforge.net/projects/unxutils ). skopiuj je do miejsca na swojej ścieżce, np. c:\windows', i będziesz mógł włączyć je do swoich skryptów.

To nie jest idealne rozwiązanie (lub to, o które prosiłeś), ale przyzwoita praca-a-round.

 1
Author: brian newman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-27 14:58:23

Aby utworzyć skompresowane archiwum możesz użyć narzędzia MAKECAB.EXE

 1
Author: lupok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-26 13:59:58