La compression ZIP intégrée à Windows peut-elle être scriptée ?
-
09-06-2019 - |
Question
La compression ZIP intégrée à Windows XP/Vista/2003/2008 peut-elle être scriptée ?Quel exécutable devrais-je appeler à partir d’un fichier BAT/CMD ?ou est-il possible de le faire avec VBScript ?
Je me rends compte que c'est possible en utilisant WinZip, 7 fermetures éclair et d'autres applications externes, mais je recherche quelque chose qui ne nécessite l'installation d'aucune application externe.
La solution
Il existe des méthodes VBA pour fermeture éclair et décompresser en utilisant également les fenêtres intégrées à la compression, ce qui devrait donner un aperçu du fonctionnement du système.Vous pourrez peut-être intégrer 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 comme un répertoire et le copier vers et depuis celui-ci.Donc pour créer un nouveau fichier zip, il vous suffit de créer un fichier avec l'extension .zip
qui a le bon en-tête pour un fichier zip vide.Ensuite, vous le fermez et dites à Windows que vous souhaitez y copier des fichiers comme s'il s'agissait d'un autre répertoire.
La décompression est plus facile – il suffit de la traiter comme un répertoire.
Au cas où les pages Web seraient à nouveau perdues, voici quelques extraits de code pertinents :
FERMETURE ÉCLAIR
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ÉCOMPRESSER
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
Autres conseils
Oui, cela peut être scripté avec VBScript.Par exemple, le code suivant peut créer un 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 implémentation complète de Unzip/Zip dans VBScript.
Si vous effectuez une vérification de la taille toutes les 500 ms plutôt qu'un nombre d'éléments, cela fonctionne mieux pour les fichiers volumineux.Win 7 écrit le fichier instantanément même s'il n'a pas fini de compresser :
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 d'énormes quantités de fichiers journaux.
Juste pour plus de clarté :GZip n'est pas un algorithme exclusivement MS, comme le suggère Guy Starbuck dans son commentaire d'août.Le GZipStream dans System.IO.Compression utilise l'algorithme Deflate, tout comme la bibliothèque zlib, et de nombreux autres outils zip.Cette classe est entièrement interopérable avec les utilitaires Unix comme gzip.
La classe GZipStream n'est pas scriptable à partir de la ligne de commande ou de VBScript, pour produire des fichiers ZIP, elle ne constituerait donc pas à elle seule une réponse à la demande de l'auteur d'origine.
Le gratuit DotNetZip La bibliothèque lit et produit des fichiers zip et peut être scriptée à partir de VBScript ou Powershell.Il comprend également des outils de ligne de commande pour produire et lire/extraire des fichiers zip.
Voici du code pour 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 du 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 un fichier .bat ou .cmd, vous pouvez utiliser les outils zipit.exe ou unzip.exe.Par exemple:
zipit NewZip.zip -s "This is string content for an entry" Readme.txt src
Voici ma tentative de résumer les fonctionnalités intégrées des fenêtres de compression et de décompression : Comment puis-je compresser (/ zip ) et décompresser (/ unzip ) des fichiers et des dossiers avec un fichier batch sans utiliser d'outils externes ?
avec quelques solutions données qui devraient fonctionner sur presque toutes les machines Windows.
En ce qui concerne le shell.application et WSH j'ai préféré le jscriptcar il permet un fichier hybride batch/jscript (avec l'extension .bat) qui ne nécessite pas de fichiers temporaires. J'ai mis les capacités de décompression et de zip dans un seul fichier ainsi que quelques fonctionnalités supplémentaires.
Il existe à la fois des exécutables zip et unzip (ainsi qu'une multitude d'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 une solution décente.
pour créer une archive compressée vous pouvez utiliser l'utilitaire MAKECAB.EXE