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

111

J'ai un fichier de commandes qui génère un fichier texte. Je pensais que ce serait bien si je pouvais le télécharger aussi.

Cela sera utilisé dans un environnement incontrôlé. Par conséquent, je ne peux pas présumer de la présence de logiciels tiers tels que 7-Zip , etc. Cette fonctionnalité doit utiliser la fonctionnalité désormais intégrée de Windows pour compresser les fichiers.

Aaron Bush
la source
1
pouvez-vous utiliser les scripts Powershell ou WSH? c'est peut-être le seul moyen d'utiliser le traitement zip intégré de Windows à partir de la ligne de commande. autrement, comme le souligne Molly, vous avez besoin d'un outil tiers.
Quack Quichotte
1
vous envoyez donc un fichier de commandes à quelqu'un et vous ne pouvez pas lui envoyer de minuscules gzip.exe liés de manière statique?
Akira
La question du PO est excellente (malgré l’accusation étrange de @quackquixote). 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 à un outil tiers qui peut être équivalent ou non.
Jon Coombs
Ceci est lié par Tomas a un script bien écrit pour compresser le contenu d'un dossier. Pour que cela fonctionne, il suffit de copier le script dans un fichier de commandes et de l'exécuter en spécifiant le dossier à compresser (source). Inutile de mentionner le répertoire de destination car il est défini par défaut dans le script sur le bureau ("% USERPROFILE% \ Desktop")
Date:
3
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:

85

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

Un accès en écriture est requis pour le parent du dossier stocké dans TEMPDIR. Comme ce n'est souvent pas le cas, il TEMPDIRpeut être nécessaire de modifier la racine du lecteur C.

Un accès en écriture est également requis pour le dossier dans .batlequel se trouve le script (car il y génère un fichier).

Veuillez également noter 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érez le .zipfichier et renommez-le.

Peter Mortensen
la source
3
@quack je tenais dans l'espoir d'une obscure commande que je ne connaissais pas. Je peux voir comment vous pourriez trouver qu’une exigence difficile s’il n’existait pas, ne voulait mettre personne à la porte.
Aaron Bush
@PeterMortensen: Il peut être intéressant de voir à quel point cela est simplifié avec Powershell. Voici un exemple sur 5 lignes , mais il existe également une write-zipapplet de commande pouvant être téléchargée à partir de Pscx .
Tamara Wijsman
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 d'utiliser un code de lot. Je sais que je peux utiliser un php bancompile'd avec argv et lui transmettre 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 FILETOZIPdans un dossier, non?
Nam G VU
@ Peter Mortensen, je sais que c'est un vieux fil, et c'est presque ce que je recherche. Existe-t-il une option pour compresser un gros fichier en morceaux plus petits?
JohnG
38

Il est possible de compresser des fichiers sans installation de logiciel supplémentaire (je l’ai testé). La solution est:

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

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

Où le fichier zip.vbscontient:

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

' Create an 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. Cela peut fonctionner si des guillemets sont placés autour des paramètres de ligne de commande.


Comment ça marche: la fonctionnalité zip intégrée à Windows (Windows XP et ultérieur?) Est exposée via des interfaces COM à partir du shell Windows, explorer.exe, c'est-à-dire 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 que le script soit complètement autonome, il crée un fichier ZIP vide pour commencer (vous pouvez é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 dans chaque version de bureau de Microsoft Windows depuis Windows 98.

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

Peter Mortensen
la source
1
+1 Bonne solution qui "Just Run", mais j'ai choisi BAT pour plusieurs autres raisons non listées. Je préférerais donc une solution BAT.
Aaron Bush
4
@Aaron Bush: ce script et Beaner fournissent tous les deux une commande permettant de compresser un fichier sur la ligne de commande, à l'aide des fonctions intégrées de Windows, comme demandé. vous pouvez ajouter cette commande à un fichier batch comme n'importe quel autre.
Quack Quichote
Notez que les chemins transmis doivent être absolus et non relatifs. Je devais aussi utiliser les techniques de la réponse ici: stackoverflow.com/q/1645843/99640
Chuck Wilbur
Les chemins doivent être absolus et il semble y avoir un échec aléatoire :(
kixorz
Ceci devrait être choisi comme réponse.
Le duc de Marshall dimanche
12

Si vous êtes prêt à utiliser PowerShell , les fonctionnalités zip sont disponibles dans .NET 2.0 (PowerShell est .NET). Voici un exemple ( 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)}
Beaner
la source
C'est fondamentalement 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 pense que cela pourrait aussi être sensible à la question du timing.
Robert Schmidt
2
La classe .NET System.IO.Compression.ZipFile a été ajoutée à la version 4.5.
Gannet en béton
7

Vous pouvez éliminer le risque de dépassement du délai imparti lors de la compression en recherchant l'existence de la fenêtre de dialogue de compression. Cette méthode gère également l’annulation par l’utilisateur 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
George Yockey
la source
1
+1 Ces codes "à la manière des singes" .Sleep(whatever)"me rendent malade.
ivan_pozdeev
1
Si j'exécute un vbs avec la logique ci-dessus pour attendre, comment cela sera-t-il géré s'il est lancé via une tâche planifiée (aucun utilisateur n'est physiquement connecté)?
Wes
5

Si vous parvenez à installer les outils du kit de ressources , vous trouverez un outil de ligne de commande appelé COMPRESS pouvant créer des fichiers d’archives compressés tels que 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.
cowgod
la source
3
+1 Ne résout pas vraiment les problèmes, mais reste utile à connaître.
Aaron Bush
3
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop
Jiří Kočara
la source
exactement ce que je cherchais .. mais cela me donne une erreur "manquant sur un fichier Zip vide"
Sonic Soul
Pour une raison quelconque, cela n’incrémente jamais, si j’imprime objShell.NameSpace( ZipFile ).Items.Countdans la boucle, il reste toujours 0 même si le fichier zip est créé et qu’il contient le contenu attendu ...
Thom Nichols
2

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
Olc
la source
2

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, je ne peux donc pas dormir pendant 2 secondes sans m'en soucier. J'ai glané la solution de contournement ici , qui est également similaire à la réponse de Jiří Kočara ici .

Cela entraînera un ping du dossier de destination toutes les 200 ms, ce qui correspond à peu près aussi rapidement 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
kayleeFrye_onDeck
la source
1

Voici ma tentative pour résumer les fenêtres de 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 shell.application et WSH, j’ai préféré le jScript, car il autorise un fichier batch / jScript hybride (avec l’extension .bat) qui ne nécessite pas de fichiers temporaires. .

npocmaka
la source
0

Si vous utilisez Windows 8 ou Windows Server 2012, vous aurez PowerShell et .NET 4.5 pour pouvoir le faire:

zip.ps1 (utilisation :)-directory <directory to zip up> -name <zip name> :

param (
    [string]$directory,
    [string]$name
)

Add-Type -Assembly System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($directory, $name, [System.IO.Compression.CompressionLevel]::Optimal, $false)

zip.bat (si vous avez besoin d'un assistant pour appeler PowerShell, le répertoire est le premier argument et le nom du zip en second):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"
Hashbrown
la source
0

Windows 10 build 17063 ou version ultérieure est fourni avec tar.exe, qui est capable de fonctionner avec zip à partir de la ligne de commande.

tar.exe -xf archive.zip

ou créer des archives

tar.exe -cf Test.zip Test
venimus
la source
-5

La ligne de commande Windows fournit maintenant la commande compacte qui, pour autant que je sache, est native de Windows. Cela devrait répondre aux exigences demandées à moins que je manque quelque chose.

utilisateur228211
la source
9
compactexiste depuis XP et est un outil pour gérer la compression NTFS
Der Hochstapler