web-dev-qa-db-fra.com

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

J'ai un fichier de commandes qui génère un fichier texte. Je pensais que ce serait bien si je pouvais le refermer 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. Ceci doit utiliser la capacité désormais intégrée de Windows pour: Fichiers Zip.

102
Aaron Bush

Voici une solution de fichier de traitement par lots (une variante de mon autre réponse) qui compressera un fichier nommé c:\ue_english.txt et le placera 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 pour la racine du lecteur C, il peut être nécessaire de modifier TEMPDIR.

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

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érez le fichier .Zip et renommez-le.

84
Peter Mortensen

Ilestpossible de compresser des fichiers Zip sans l’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.Zip contenant tous les fichiers du dossier C:\test3:

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

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


Comment cela fonctionne: la fonctionnalité Zip intégrée à Windows (Windows XP et versions ultérieures?) Est exposée via COM interfaces à partir du shell Windows, Explorer.exe - c’est le "Shell "Application". Cette interface COM peut être utilisée à partir de VBScript script car un tel script peut accéder aux composants COM. Pour que le script soit totalement autonome, il crée un fichier Zip vide pour le démarrage (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.exe fait 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é.

37
Peter Mortensen

Si vous êtes prêt à utiliserPowerShell, les fonctionnalités Zip sont disponibles dans .NET 2.0 (PowerShell est .NET). Voici un exemple ( source ) à 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)}
12
Beaner

Vous pouvez éliminer le risque de dépassement du délai imparti lors de la compression en interrogeant 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
7
George Yockey

Si vous parvenez à installer Outils du kit de ressources , vous trouverez un outil de ligne de commande appelé COMPRESS pouvant 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
cowgod
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop
3
Jiří Kočara

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 dit de vérifier les mises à jour 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

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
Olc

Voici ma tentative de synthèse des capacité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- et-dossiers-avec-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 car il permet de créer un fichier batch/jscript hybride (avec une extension .bat) ne nécessitant pas de fichier temporaire. Décompressez et compressez les fonctionnalités Zip dans un seul fichier et quelques fonctionnalités supplémentaires.

1
npocmaka

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 Zip en second):

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