Question Pouvez-vous compresser un fichier à partir de l'invite de commande en utilisant uniquement la fonctionnalité intégrée de Windows pour compresser les fichiers?


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

Cela sera utilisé dans un environnement non contrôlé, de sorte que je ne peux pas faire de suppositions sur la présence de produits logiciels tiers tels que 7-zip, etc. Ceci doit utiliser la fonctionnalité maintenant intégrée de Windows pour compresser des fichiers.


93
2018-02-19 19:46


origine


pouvez-vous utiliser des scripts Powershell ou WSH? c'est peut-être la seule façon d'utiliser la gestion zip intégrée de Windows à partir de la ligne de commande. sinon, comme le souligne Molly, vous avez besoin d'un outil tiers. - quack quixote
vous envoyez donc à quelqu'un un fichier de commandes et vous ne pouvez pas lui envoyer de minuscules fichiers gzip.exe liés statiquement? - akira
La question de l'OP est excellente (malgré l'accusation étrange de @quackquixote). Étant donné que Windows fournit cela en un seul clic sous SendTo, devrait être une commande utilisable dans un fichier BAT. C'est donc une bonne question, même si la réponse est non et que l'on doit (ridiculement) recourir à un outil tiers qui peut ou non être équivalent. - Jon Coombs
C'est lien par Tomas a un script bien écrit pour compresser le contenu d'un dossier. Pour que cela fonctionne, copiez le script dans un fichier de commandes et exécutez-le en spécifiant le dossier à compresser (source). Pas besoin de mentionner le répertoire de destination tel qu'il est défini par défaut dans le script pour Desktop ("% USERPROFILE% \ Desktop") - Abhijeet
Le plus simple serait, dans une invite de commande: powershell.exe Compress-Archive file-to-zip.txt zippedfile.zip (ça marche aussi avec le dossier) - ThomasGuenet


Réponses:


Voici une solution de fichier tout en lot (une variante de mon autre réponse) qui va compresser un fichier nommé c:\ue_english.txt et le mettre 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

L'accès en écriture est requis pour le parent du dossier stocké dans TEMPDIR. Comme ce n'est souvent pas le cas pour la racine du lecteur C TEMPDIR peut devoir être changé.

Un accès en écriture est également requis pour le dossier du .bat le script est dans (car il génère un fichier là).

Notez également que l’extension du fichier compressé doit être .zip. Toute tentative d'utilisation d'une autre extension peut entraîner une erreur de script. Au lieu de cela, générer le .zip fichier et le renommer.


81
2018-02-22 17:28



@quack je tenais dans l'espoir d'un commandement obscur que je ne connaissais pas. Je peux voir comment vous pourriez trouver qu’une exigence difficile, si elle n’existe pas, ne voulait pas dire mettre qui que ce soit. - Aaron Bush
@ PeterMortensen: Il peut être intéressant de voir combien cela est simplifié avec Powershell. Voici un exemple de 5 lignes, mais il existe aussi un write-zip applet de commande qui peut être téléchargée à partir du Pscx. - Tom Wijsman
J'ai utilisé zip.exe et cywin1.dll (3mb) pour satisfaire le ZIP et l'utilisation est une ligne ... à partir du zip lui-même d'utiliser un code de lot. Je sais que je peux utiliser un php bancompile avec argv et y passer un fichier. Cela paraît bien. "Un zip de la ligne de commande Windows" est un vieux film de science-fiction, non? - erm3nda
Pourquoi devons-nous utiliser un dossier temporaire TEMPDIR? Je pense que votre intention est d'envelopper le fichier FILETOZIP par un dossier non? - Nam G VU
@ Peter Mortensen, je sais que c'est un vieux sujet, et c'est presque ce que je recherche. Existe-t-il une option pour compresser un gros fichier en morceaux plus petits? - JohnG


Il est possible de compresser des fichiers sans installation de tout autre logiciel (je l'ai testé). La solution est la suivante:

Exécuter 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ù fichier zip.vbs contient:

'Get command-line arguments.
Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

'Create empty ZIP file.
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)

'Required to let the zip command execute
'If this script randomly fails or the zip file is not complete, 
'just increase to more than 2 seconds
wScript.Sleep 2000

Je ne l'ai pas testé pour les chemins et les noms de fichiers contenant des espaces. Il peut fonctionner si citations sont mis autour des paramètres de la ligne de commande.


Comment ça marche: la fonctionnalité zip intégrée dans Windows (Windows XP et versions ultérieures) est exposé à travers COM interfaces du shell Windows , explorer.exe - c'est la partie "Shell.Application". Cette interface COM peut être utilisée à partir d'un VBScript script parce que Un tel script peut accéder aux composants COM. Pour que le script soit totalement 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 a été installé par défaut sur chaque bureau version 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é.


35
2018-02-20 15:48



+1 Bonne solution qui "Just Run", mais je choisis BAT pour plusieurs autres raisons non répertoriées. Je préférerais donc une solution BAT. - Aaron Bush
@Aaron Bush: ce script et celui de Beaner fournissent tous deux une commande qui zippe un fichier sur la ligne de commande, en utilisant les fonctions intégrées à Windows, comme demandé. vous pouvez ajouter cette commande à un fichier batch comme n'importe quel autre. - quack quixote
Notez que les chemins d'accès doivent être absolus et non relatifs. Je devais aussi utiliser les techniques dans la réponse ici: stackoverflow.com/q/1645843/99640 - Chuck Wilbur
Les chemins doivent être absolus et il semble échouer au hasard :( - kixorz
Ceci devrait être choisi comme réponse. - The Duke Of Marshall שלום


Si vous êtes ouvert à utiliser PowerShell, les fonctionnalités zip sont disponibles dans .NET 2.0 (PowerShell est .NET). Voici un exemple (la source) crédit à Mike Hodnick:

########################################################
# out-zip.ps1
#
# Usage:
#    To zip up some files:
#       ls c:\source\*.txt | out-zip c:\target\archive.zip $_
#
#    To zip up a folder:
#       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)}

11
2018-02-19 21:59



C'est fondamentalement la même chose que le code CScript dans les 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 du calendrier. - Robert Schmidt
La classe .NET System.IO.Compression.ZipFile a été ajoutée dans la version 4.5. - Concrete Gannet


Vous pouvez éliminer le risque de dépassement de délai pendant la compression en interrogeant l'existence de la fenêtre de dialogue de compression. Cette méthode permet également à l'utilisateur d'annuler sa sortie de la fenêtre de compression.

objShell.NameSpace(ZipFile).CopyHere(source)

' Wait for compression window to open
set scriptShell = CreateObject("Wscript.Shell")
Do While scriptShell.AppActivate("Compressing...") = FALSE   
   WScript.Sleep 500 ' Arbitrary polling delay
Loop  

' Wait for compression to complete before exiting script
Do While scriptShell.AppActivate("Compressing...") = TRUE   
   WScript.Sleep 500 ' Arbitrary polling delay
Loop

7
2017-11-23 00:47



+1. Ces codes de style singe ".Sleep(whatever)" me rendre malade. - ivan_pozdeev
Si j'exécute une vbs avec la logique ci-dessus pour l'attendre, comment sera-t-elle gérée si elle est lancée via une tâche planifiée (où aucun utilisateur n'est physiquement connecté). - Wes


Si vous pouvez installer le Outils du kit de ressources, vous trouverez un outil de ligne de commande appelé COMPRESS qui peut créer des fichiers d'archive compressés comme zip.

Microsoft (R) File Compression Utility  Version 5.00.2134.1
Copyright (C) Microsoft Corp. 1990-1999.  All rights reserved.

Compresses one or more files.

COMPRESS [-r] [-d] [-z] Source Destination
COMPRESS -r [-d] [-z] Source [Destination]

  -r            Rename compressed files.
  -d            Update compressed files only if out of date.
  -zx           LZX compression.
  -z            MS-ZIP compression.
  -zq[n]        Quantum compression and optional level
                (in range 1-7, default is 4).
  Source        Source file specification.  Wildcards may be used.
  Destination   Destination file | path specification.
                Destination may be a directory.
                If Source is multiple files and -r is not specified,
                Destination must be a directory.

4
2018-02-19 20:29



+1 Ne résout pas vraiment les problèmes, mais reste intéressant à connaître. - Aaron Bush


'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop

3
2017-08-07 07:46



exactement ce que je cherchais ... mais cela me donne une erreur "manquant sur le fichier Zip vide" - Sonic Soul
Pour une raison quelconque, cela n'incrémente jamais, si j'imprime objShell.NameSpace( ZipFile ).Items.Count à l'intérieur de la boucle, il est toujours 0 même si le fichier zip est créé et qu'il contient le contenu attendu à l'intérieur ... - Thom Nichols


Plusieurs fichiers / répertoires avec code simplifié.

cscript zip.vbs target.zip sourceFile1 sourceDir2 ... sourceObjN

Fichier zip.vbs

Set objArgs = WScript.Arguments
ZipFile = objArgs(0)

' Create empty ZIP file and open for adding
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set zip = CreateObject("Shell.Application").NameSpace(ZipFile)

' Add all files/directories to the .zip file
For i = 1 To objArgs.count-1
  zip.CopyHere(objArgs(i))
  WScript.Sleep 10000 'REQUIRED!! (Depending on file/dir size)
Next

2
2017-11-05 21:06





Ceci est une mutation de la réponse acceptée. Je fais une tonne de tâches d'automatisation sur des milliers de fichiers à la fois, donc je ne peux pas simplement dormir pendant 2 secondes et ne pas m'en préoccuper. J'ai glané la solution de contournement ici, qui est également similaire à la réponse de Jiří Kočara ici.

Cela entraînera le ping du dossier de destination toutes les 200 ms, ce qui est approximativement aussi rapide que Microsoft le dit pour vérifier les mises à jour de FS.

Set parameters = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
SourceDir = FS.GetAbsolutePathName(parameters(0))
ZipFile = FS.GetAbsolutePathName(parameters(1))
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set shell = CreateObject("Shell.Application")
Set source_objects = shell.NameSpace(SourceDir).Items
Set ZipDest = shell.NameSpace(ZipFile)
Count=ZipDest.Items().Count
shell.NameSpace(ZipFile).CopyHere(source_objects)
Do While Count = ZipDest.Items().Count
    wScript.Sleep 200
Loop

2
2018-06-07 21:53





Voici ma tentative de résumer les fonctionnalités intégrées pour la compression et la décompression - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders-with-batch-f

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 jscript comme il permet un fichier hybride batch / jscript (avec l'extension .bat) qui ne nécessite pas de fichiers temporaires.J'ai mis des capacités de décompression et zip dans un seul fichier et quelques fonctionnalités supplémentaires.


1
2018-01-22 12:31