131 votes

Pouvez-vous compresser un fichier depuis l'invite de commandes en utilisant UNIQUEMENT la capacité intégrée de Windows à compresser des fichiers?

J'ai un fichier batch qui génère un fichier texte. Je pensais que ce serait bien si je pouvais aussi le compresser.

Ceci sera utilisé dans un environnement non contrôlé, donc je ne peux pas faire d'hypothèses sur la présence de produits logiciels tiers tels que 7-Zip, etc. Il est nécessaire d'utiliser la capacité de compression de fichiers intégrée à Windows.

1 votes

Pouvez-vous utiliser PowerShell ou un script WSH ? Cela pourrait être le seul moyen d'utiliser la gestion intégrée des fichiers zip de Windows en ligne de commande. Sinon, comme l'a souligné Molly, vous aurez besoin d'un outil tiers.

2 votes

Ainsi, vous envoyez à quelqu'un un fichier batch et vous ne pouvez pas lui envoyer un petit fichier gzip.exe statiquement lié ?

0 votes

La question de l'OP est excellente (accusation étrange de @quackquixote mise à part). Puisque Windows fournit cela en un seul clic sous SendTo, il devrait y avoir une commande utilisable dans un fichier BAT. C'est donc une bonne question même si la réponse est non et qu'il faut (ridiculement) recourir à l'utilisation d'un outil tiers qui peut être équivalent ou non.

95voto

Adam V Points 2774

Voici une solution de fichier batch complète (une variation de ma réponse précédente) qui compressera un fichier nommé c:\ue_english.txt et le mettra dans C:\someArchive.zip:

set FILETOZIP=c:\ue_english.txt

set TEMPDIR=C:\temp738
rmdir %TEMPDIR%
mkdir %TEMPDIR%
xcopy /s %FILETOZIP% %TEMPDIR%

echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
echo wScript.Sleep 2000 >> _zipIt.vbs

CScript  _zipIt.vbs  %TEMPDIR%  C:\someArchive.zip

pause

Un accès en écriture est requis pour le dossier parent du répertoire stocké dans TEMPDIR. Comme c'est souvent pas le cas pour la racine du lecteur C, TEMPDIR devra peut-être être modifié.

Un accès en écriture est également requis pour le dossier dans lequel se trouve le script .bat (car il génère un fichier à cet endroit).

Aussi, veuillez noter que l'extension de fichier pour le fichier compressé doit être .zip. Des tentatives d'utilisation d'une autre extension peuvent entraîner une erreur de script. Au lieu de cela, générez le fichier .zip et renommez-le.

3 votes

@quack Je me suis retenu dans l'espoir d'une commande obscure que je ne connaissais pas. Je comprends que ce puisse être une exigence difficile s'il n'y en a pas, je ne voulais pas importuner qui que ce soit.

0 votes

@PeterMortensen: Il peut être intéressant de voir à quel point cela est simplifié avec Powershell. Voici un exemple en 5 lignes, mais il existe également une commande write-zip qui peut être téléchargée depuis le Pscx.

0 votes

J'ai utilisé le zip.exe et cywin1.dll (3mb) pour satisfaire le ZIP et l'utilisation est une ligne... du zip lui-même en utilisant un code batch. Je sais que je peux utiliser un php bancompile'd avec argv et lui passer un fichier. Ça a l'air cool. "Un zip à partir de la ligne de commande de Windows" est un vieux film de science-fiction, n'est-ce pas?

41voto

Adam V Points 2774

Il est possible de compresser des fichiers sans installer de logiciel supplémentaire (je l'ai testé). La solution est la suivante :

Exécutez ceci dans une fenêtre de ligne de commande pour créer un fichier ZIP nommé C:\someArchive.zip contenant tous les fichiers du dossier C:\test3 :

CScript  zip.vbs  C:\test3  C:\someArchive.zip

Où le fichier zip.vbs contient :

' Récupérer les arguments de la ligne de commande.
Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

' Créer un fichier ZIP vide.
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")

Set source = objShell.NameSpace(InputFolder).Items

objShell.NameSpace(ZipFile).CopyHere(source)

' Nécessaire pour laisser le processus ZIP s'exécuter
' Si ce script échoue de manière aléatoire ou si le fichier ZIP est incomplet,
' augmentez simplement à plus de 2 secondes
wScript.Sleep 2000

Je ne l'ai pas testé pour les chemins et les noms de fichiers contenant des espaces. Cela peut fonctionner si des guillemets sont placés autour des paramètres de ligne de commande.


Fonctionnement : la fonctionnalité de compression intégrée dans Windows (Windows XP et ultérieur ?) est exposée via des interfaces COM à partir de l'interface Windows shell, explorer.exe - c'est la partie "Shell.Application". Cette interface COM peut être utilisée à partir d'un script VBScript car un tel script peut accéder aux composants COM. Pour rendre le script entièrement autonome, il crée un fichier ZIP vide pour commencer (on pourrait également créer un fichier ZIP vide et le copier sur le système cible avec le script VBScript).

VBScript est installé par défaut dans chaque version de bureau de Microsoft Windows depuis Windows 98.

CScript.exe fait partie de Windows Script Host. Windows Script Host est distribué et installé par défaut sur Windows 98 et les versions ultérieures de Windows. Il est également installé si Internet Explorer 5 (ou une version ultérieure) est installé.

1 votes

+1 Bonne solution qui va "Just Run", mais je choisis BAT pour plusieurs autres raisons non mentionnées. Donc, je préférerais une solution BAT.

4 votes

@Aaron Bush: ce script et Beaner's fournissent tous les deux une commande qui compresse un fichier en ligne de commande, en utilisant les fonctions intégrées de Windows, comme demandé. vous pouvez ajouter cette commande à un fichier batch comme n'importe quel autre.

0 votes

Notez que les chemins indiqués doivent être absolus, pas relatifs. J'ai dû également utiliser les techniques de la réponse ici : stackoverflow.com/q/1645843/99640

27voto

venimus Points 1270

Windows 10 version 17063 ou ultérieure est livré avec tar.exe capable de travailler avec des fichiers ZIP en ligne de commande.

tar.exe -xf archive.zip

Ou pour créer une archive ZIP :

tar.exe -a -cf Test.zip Test

6 votes

Utilisez uniquement l'option -a lors de la création. Sinon, il considère une archive tar simple.

1 votes

Wow .. this works but is not documenté anywhere as far as I can see

2 votes

Interrupteurs sont documentés ici: freebsd.org/cgi/man.cgi?query=bsdtar&sektion=1 .. -a signifie "auto-compresser" où le format est déduit de l'extension

12voto

Junfeng Points 361

Si vous êtes ouvert à l'utilisation de PowerShell, les capacités de compression sont disponibles dans .NET 2.0 (PowerShell est .NET). Voici un exemple (source) crédit à Mike Hodnick:

########################################################
# out-zip.ps1
#
# Usage:
#    Pour compresser des fichiers :
#       ls c:\source\*.txt | out-zip c:\target\archive.zip $_
#
#    Pour compresser un dossier :
#       gi c:\source | out-zip c:\target\archive.zip $_
########################################################

$path = $args[0]
$files = $input

if (-not $path.EndsWith('.zip')) {$path += '.zip'} 

if (-not (test-path $path)) { 
  set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
} 

$ZipFile = (new-object -com shell.application).NameSpace($path) 
$files | foreach {$zipfile.CopyHere($_.fullname)}

0 votes

C'est essentiellement la même chose que le code CScript dans d'autres réponses. Aucune fonctionnalité .NET n'est utilisée (et .NET n'a de toute façon pas de support ZIP). Je soupçonne que cela pourrait également être sensible à la question de timing.

3 votes

La classe .NET System.IO.Compression.ZipFile a été ajoutée dans la version 4.5.

7voto

Balthier Points 291

Vous pouvez éliminer le risque d'expiration pendant la compression en vérifiant si la fenêtre de dialogue de compression existe. Cette méthode gère également l'annulation par l'utilisateur de la compression.

objShell.NameSpace(ZipFile).CopyHere(source)

' Attendre l'ouverture de la fenêtre de compression
set scriptShell = CreateObject("Wscript.Shell")
Do While scriptShell.AppActivate("Compression en cours...") = FALSE   
   WScript.Sleep 500 ' Délai de sondage arbitraire
Loop  

' Attendre que la compression soit terminée avant de quitter le script
Do While scriptShell.AppActivate("Compression en cours...") = TRUE   
   WScript.Sleep 500 ' Délai de sondage arbitraire
Loop

1 votes

+1. Ces singes de code de style ".Sleep(whatever)" me rendent malade.

2 votes

Si je lance un script vbs avec la logique ci-dessus pour l'attente, comment cela sera-t-il géré s'il est lancé via une tâche planifiée (où aucun utilisateur n'est physiquement connecté)?

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X