60 votes

La compression ZIP intégrée à Windows peut-elle être scriptée?

La compression ZIP intégrée à Windows XP / Vista / 2003/2008 peut-elle être scriptée? Quel exécutable devrais-je appeler depuis un fichier BAT / CMD? ou est-il possible de le faire avec VBScript?

Je réalise que cela est possible avec WinZip , 7-Zip et d’autres applications externes, mais je cherche quelque chose qui ne nécessite aucune application externe.

33voto

Adam Davis Points 47683

Il y a VBA méthodes de zip et le décompresser à l'aide de la windows intégré à la compression, ce qui devrait donner un aperçu de la façon dont le système fonctionne. Vous pouvez être en mesure de construire ces méthodes dans un langage de script de votre choix.

Le principe de base est que dans windows, vous pouvez traiter un fichier zip dans un répertoire, et copiez-le dans et hors de lui. Ainsi, pour créer un nouveau fichier zip, il vous suffit de faire un fichier avec l'extension .zip qui a le droit d'en-tête est vide de fichier zip. Ensuite, vous fermez, et de dire à windows que vous souhaitez copier des fichiers dedans comme si c'était un autre répertoire.

La décompression est plus facile - il suffit de le traiter comme un répertoire.

Dans le cas où les pages web sont encore perdu, voici quelques extraits de code pertinentes:

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

DÉCOMPRESSEZ

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

26voto

Jay Points 20373

Oui, cela peut être scripté avec VBScript. Par exemple, le code suivant peut créer une archive zip à partir d'un répertoire:

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

Vous pouvez également trouver http://www.naterice.com/blog/template_permalink.asp?id=64 utile car il inclut une pleine Unzip Zip de mise en œuvre dans VBScript.

Si vous effectuez une vérification de la taille de toutes les 500 ms plutôt que d'un élément de comte, il fonctionne mieux pour les gros fichiers. Win 7 écrit le fichier instantanément bien que ce n'est pas terminé la compression:

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

Fonctionne très bien pour les énormes quantités de fichiers journaux.

5voto

Cheeso Points 87022

Juste pour plus de clarté: GZip n'est pas un MS-seulement l'algorithme tel que suggéré par Guy Starbuck dans son commentaire à partir d'août. Le GZipStream dans le Système.IO.Compression utilise l'algorithme Deflate, tout de même que la bibliothèque zlib, et de nombreux autres zip outils. Cette classe est entièrement interopérable avec les utilitaires unix comme gzip.

Le GZipStream classe n'est pas scriptable de la ligne de commande, ou VBScript, pour produire des fichiers ZIP, de sorte qu'il ne saurait à lui seul constituer une réponse à l'affiche originale de la demande.

La libre DotNetZip bibliothèque n'lire et produire des fichiers zip, et peuvent être envoyés à partir de VBScript ou Powershell. Il comprend également des outils de ligne de commande pour produire et lire/extraire des fichiers zip.

Voici un code 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.")

Voici un code pour 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");

Dans une .bat ou .cmd fichier, vous pouvez utiliser le zipit.exe ou unzip.exe outils. Par exemple:

zipit NewZip.zip  -s "This is string content for an entry"  Readme.txt  src 

1voto

brian newman Points 1304

Il existe des exécutables zip et unzip (ainsi que de nombreuses autres applications utiles) dans le package UnxUtils disponible sur SourceForge ( http://sourceforge.net/projects/unxutils ). Copiez-les dans un emplacement de votre PATH, tel que 'c: \ windows', et vous pourrez les inclure dans vos scripts.

Ce n'est pas la solution parfaite (ou celle que vous avez demandée) mais un travail décent.

1voto

lupok Points 182

pour créer une archive compressée, vous pouvez utiliser l'utilitaire MAKECAB.EXE

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X