2010-02-19 19:46:23 +0000 2010-02-19 19:46:23 +0000
113
113

¿Puedes comprimir un archivo desde el símbolo del sistema usando la capacidad incorporada de Windows para comprimir archivos?

Tengo un archivo por lotes que produce un archivo de texto. Pensé que sería bueno si pudiera comprimirlo también.

Esto será usado en un ambiente no controlado, así que no puedo hacer suposiciones sobre la presencia de productos de software de terceros como 7-Zip , etc. Esto necesita usar la capacidad ya incorporada de Windows para comprimir archivos.

Respuestas (12)

86
86
86
2010-02-22 17:28:45 +0000

Aquí hay una solución de archivo por lotes (una variación de mi otra respuesta) que comprimirá un archivo llamado c:\ue_english.txt y lo pondrá en 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

Se requiere acceso de escritura al padre de la carpeta almacenada en TEMPDIR. Como a menudo no es el caso de la raíz de la unidad C TEMPDIR puede tener que cambiarse.

El acceso de escritura también es necesario para la carpeta en la que se encuentra el script .bat (ya que genera un archivo allí).

Además, tenga en cuenta que la extensión del archivo para el archivo comprimido debe ser .zip. Los intentos de utilizar otra extensión pueden dar lugar a un error de escritura. En su lugar, genere el archivo .zip y cámbiele el nombre.

40
40
40
2010-02-20 15:48:33 +0000

Es posible comprimir archivos sin necesidad de instalar ningún software adicional (lo he probado). La solución es:

Ejecute esto en una ventana de línea de comandos para crear un archivo ZIP llamado C:\someArchive.zip que contenga todos los archivos de la carpeta C:\test3:

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

Donde el archivo zip.vbs contiene:

' 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

No lo he probado en cuanto a rutas y nombres de archivos que contengan espacios. Puede funcionar si se ponen comillas alrededor de los parámetros de la línea de comandos.


Cómo funciona: la funcionalidad zip incorporada en Windows (¿Windows XP y posterior?) se expone a través de las interfaces COM del shell de Windows, explorer.exe - es decir, la parte “Shell.Application”. Este interfaz COM puede ser usado desde un script VBScript porque tal script puede acceder a los componentes COM. Para que el script sea completamente autónomo, crea un archivo ZIP vacío para empezar (también se puede crear un archivo ZIP vacío y copiarlo al sistema de destino junto con el script VBScript).

VBScript ha sido instalado por defecto en cada versión de escritorio de Microsoft Windows desde Windows 98.

CScript.exe es parte de Windows Script Host . Windows Script Host se distribuye e instala de forma predeterminada en Windows 98 y versiones posteriores de Windows. También se instala si se instala Internet Explorer 5 (o una versión posterior).

12
12
12
2010-02-19 21:59:36 +0000

Si está abierto a usar * PowerShell **, las capacidades de zip están disponibles en .NET 2.0 (PowerShell es .NET). Aquí hay un ejemplo fuente ) acreditación a 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)}
7
7
7
2011-11-23 00:47:36 +0000

Puede eliminar el riesgo de que se agoten los tiempos durante la compresión mediante el sondeo de la existencia de la ventana de diálogo de compresión. Este método también maneja la cancelación de la ventana de compresión por parte del usuario.

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
5
5
5
2010-02-19 20:29:14 +0000

Si eres capaz de instalar el Kit de Herramientas de Recursos , encontrarás una herramienta de línea de comandos llamada COMPRESS que puede crear archivos comprimidos como 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.
3
3
3
2012-08-07 07:46:33 +0000
'Keep script waiting until compression is done
Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count
    WScript.Sleep 200
Loop
2
2
2
2017-06-07 21:53:59 +0000

Esta es una mutación de la respuesta aceptada. Hago una tonelada de tareas de automatización en hasta miles de archivos a la vez, así que no puedo dormir por 2 segundos y no preocuparme por ello. He recogido la solución aquí , que también es similar a la respuesta de Jiří Kočara aquí .

Esto causará que la carpeta de destino sea pinchada cada 200ms, lo que es aproximadamente tan rápido como Microsoft dice para comprobar si hay actualizaciones 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
2
2
2012-11-05 21:06:59 +0000

Múltiples archivos / directorios con código simplificado.

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

archivo 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
1
1
1
2015-01-22 12:31:49 +0000

Aquí está mi intento de resumir las capacidades incorporadas de Windows para la compresión y la descompresión - https://stackoverflow.com/questions/28043589/how-can-i-compres-zip-and-uncopress-unzip-files-and-folders-with-batch-f

con algunas soluciones dadas que deberían funcionar en casi todas las máquinas de Windows.

En cuanto a la shell.application y WSH preferí el jscript ya que permite un archivo híbrido batch/jscript (con extensión .bat) que no requiere archivos temporales.he puesto las capacidades de descompresión y compresión en un archivo más algunas características más.

1
1
1
2019-08-20 13:24:16 +0000

Windows 10 build 17063 o posterior está empaquetado con tar.exe que es capaz de trabajar con zip desde la línea de comandos.

tar.exe -xf archive.zip

o para crear un archivo

tar.exe -cf Test.zip Test
1
1
1
2016-08-02 11:19:52 +0000

Si en Windows 8 o Windows Server 2012 tendrá PowerShell y .NET 4.5 para que pueda hacer esto:

zip.ps1 (uso: -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 necesita un ayudante para llamar a PowerShell por usted, el directorio es el primer argumento y el nombre del zip el segundo):

@Echo Off
powershell -ExecutionPolicy ByPass -Command "& '%~dpn0.ps1' -directory '%1' -name '%2'"
-4
-4
-4
2013-05-31 19:54:34 +0000

La línea de comandos de Windows ahora proporciona el comando compacto que, hasta donde puedo decir, es nativo de Windows. Eso debería cumplir los requisitos solicitados a menos que se me haya pasado algo por alto.