Tutos geek

Tutoriaux linux, debian, android et autres

Créer un zip en ligne de commande

Je cherchais un moyen de créer un fichier zip sous Windows sans passer par un programme tiers (java, exe, python, ...).
Je pensais y arriver uniquement en batch mais en fait il faut faire quelques lignes de VB Script.

Le fichier batch :
@echo off

REM ----- Setup -----
set SRC_DIR=C:\Temp\FolderToZip\
set VBS_FILE=.\zipIt.vbs
set ARCHIVE_FOLDER=c:\Temp\
mkdir %ARCHIVE_FOLDER% 2> nul
set DATE_TIME=%DATE:~-4%.%DATE:~3,2%.%DATE:~0,2%-%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%
set ZIP_FILE="%ARCHIVE_FOLDER%folderZipped_%DATE_TIME%.zip"
REM ------ end -------

REM ----- Execute VBS file (creating ZIP file) -----
CScript %VBS_FILE% %SRC_DIR% %ZIP_FILE%

Le fichier VBS : zipIt.vbs
REM Récupération des arguments
Set args = WScript.Arguments
srcFolder = args(0) REM Dossier source, à zipper
zipFilePath = args(1) REM Chemin du fichier zip à créer

REM Récupération des chemins absolus
set fso = CreateObject("Scripting.FileSystemObject")
srcFolder = fso.GetAbsolutePathName(srcFolder)
zipFilePath = fso.GetAbsolutePathName(zipFilePath)

REM Magie noire...
REM Création du fichier zip (vide)
CreateObject("Scripting.FileSystemObject").CreateTextFile(zipFilePath, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")
Set zip = objShell.NameSpace(zipFilePath)
Set source = objShell.NameSpace(srcFolder)

REM REMplissage du fichier zip
REM Malheureusement cette opération est non-bloquante
zip.CopyHere source.Items

REM il faut donc attendre jusqu'à qu'elle soit terminée.
REM Pour cela on boucle tant que le nombre de fichiers dans le zip n'est pas égal au nombre de fichiers dans le dossier source.
REM http://stackoverflow.com/questions/149956/how-to-determine-when-copy-finishes-in-vbscript
Do Until zip.Items.Count = source.Items.Count
    WScript.Sleep 100
    WScript.Echo "Copie en cours : " & zip.Items.Count & "/" & source.Items.Count
Loop

Pour une raison que j'ignore le script échoue si la source contient, quelque part dans sa hiérarchie, un dossier vide.
J'obtiens le message suivant :
Windows was unable to add one or more empty directories to the Compressed (zipped) Folder.

Si quelqu'un peut m'expliquer pourquoi ou comment y remédier, ça serait sympa.

Si vous voulez un seul fichier qui fasse tout ça il est possible de créer le fichier VBS à la volée, l'exécuter puis le détruire :

@echo off

REM ----- Setup -----
set SRC_DIR=C:\Temp\FolderToZip\
set VBS_FILE=.\zipIt.vbs
set ARCHIVE_FOLDER=c:\Temp\
mkdir %ARCHIVE_FOLDER% 2> nul
set DATE_TIME=%DATE:~-4%.%DATE:~3,2%.%DATE:~0,2%-%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%
set ZIP_FILE="%ARCHIVE_FOLDER%folderZipped_%DATE_TIME%.zip"
REM ------ end -------

REM ------ Création du fichier VBS à chaud -----
REM Récupération des arguments
echo Set args = WScript.Arguments>%VBS_FILE%
echo srcFolder = args(0)>>%VBS_FILE% REM Dossier source, à zipper
echo zipFilePath = args(1)>>%VBS_FILE% REM Chemin du fichier zip à créer

REM Récupération des chemins absolus
echo set fso = CreateObject("Scripting.FileSystemObject")>>%VBS_FILE%
echo srcFolder = fso.GetAbsolutePathName(srcFolder)>>%VBS_FILE%
echo zipFilePath = fso.GetAbsolutePathName(zipFilePath)>>%VBS_FILE%

REM Magie noire...
REM Création du fichier zip (vide)
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(zipFilePath, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar)>>%VBS_FILE%

echo Set objShell = CreateObject("Shell.Application")>>%VBS_FILE%
echo Set zip = objShell.NameSpace(zipFilePath)>>%VBS_FILE%
echo Set source = objShell.NameSpace(srcFolder)>>%VBS_FILE%

REM REMplissage du fichier zip
REM Malheureusement cette opération est non-bloquante
echo zip.CopyHere source.Items>>%VBS_FILE%

REM il faut donc attendre jusqu'à qu'elle soit terminée.
REM Pour cela on boucle tant que le nombre de fichiers dans le zip n'est pas égal au nombre de fichiers dans le dossier source.
REM http://stackoverflow.com/questions/149956/how-to-determine-when-copy-finishes-in-vbscript
echo Do Until zip.Items.Count = source.Items.Count>>%VBS_FILE%
echo 	WScript.Sleep 100>>%VBS_FILE%
echo 	WScript.Echo "Copie en cours : " ^& zip.Items.Count ^& "/" ^& source.Items.Count>>%VBS_FILE%
echo Loop>>%VBS_FILE%
REM ------ end -------

REM ----- Execute VBS file (creating ZIP file) -----
CScript %VBS_FILE% %SRC_DIR% %ZIP_FILE%

REM ----- Suppression du fichier VBS ------
del %VBS_FILE%

Notez le caractère d'échappement "^" utilisé pour échapper les "&" à écrire dans le fichier.


Source
Création du zip : http://superuser.com/questions/110991/can-you-zip-a-file-from-the-command-prompt-using-only-windows-built-in-capabili
Attendre que la création du zip se termine : http://stackoverflow.com/questions/149956/how-to-determine-when-copy-finishes-in-vbscript