2012-02-09 10 views
5

quiero crear un archivo zip en PowerShell, añadir elementos al archivo zip, a continuación, obtener el contenido comprimido de ese archivo zip como bytes inmediatamente después de crear el archivo zip , en el mismo scipt El problema es que no parece que la aplicación zip haya escrito su contenido en el sistema de archivos. ¿Cómo se cierra/vacía la aplicación zip para que la siguiente declaración de PowerShell pueda obtener acceso al archivo zip recién creado?Powershell - Cómo cumplimentar/cerrar un archivo zip en powershell

Ejemplo:

new-item -type File test.zip -force 
$zip = (get-item test.zip).fullname 
$app = new-object -com shell.application 
$folder = $app.namespace($zip) 
$item = new-item file.txt -itemtype file -value "Mooo" -force 
$folder.copyhere($item.fullname) 
dir test.zip # <---- Empty test.zip file 
Get-Content -Encoding byte $zip | echo # <-- nothing echoed 

El "dir test.zip" muestra un archivo zip con ningún contenido, por lo tanto el Get-Content vuelve nada.

Tenga en cuenta que esto parece ser un problema con el comportamiento asíncrono de la acción CopyHere. Si duermo después de la línea copyhere, el archivo comprimido se completará. Sin embargo, no sé cuánto tiempo uno debe dormir, ni quiero retrasar el procesamiento.

Mucho gracias por adelantado!

+0

Nunca he creado archivos de PowerShell, pero parece que no funcionaría en absoluto. – Joey

+1

échale un vistazo aquí: http://dotnetzip.codeplex.com/. ¡Inoic.zip es mejor para trabajar con archivos zip! –

+0

Sí, de hecho funciona. Si observa el directorio en el que ejecuta estas declaraciones, encontrará que se ha creado un archivo test.zip. –

Respuesta

0

Este método para comprimir archivos no es apropiado para scripts automatizados. Esto tiene limitaciones en Windows 2003 y en el servidor de Windows XP para 3 gigas. Además, no da los errores adecuados.

+0

Después de joder con esto por un tiempo, tengo que estar de acuerdo. Invocar el shell para manipular un zip requiere mucha sobrecarga, y es extremadamente indirecto. Revisé la biblioteca Inoic.zip que mencionó @Christian, y encontré que funciona muy bien para mi caso de uso, que es crear los bytes del archivo zip sin tener que escribir en el sistema de archivos. ¡Agradezco a todos por sus soluciones creativas! –

+0

-DV no es una respuesta en absoluto ... – GoClimbColorado

0

intento de crear el archivo zip vacío como esto:

$zipfilename = "myzip.zip" 
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 

A continuación, el resto de su código.

este código en mi caja funciona:

$zipfilename = "a.zip" 
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
$app = new-object -com shell.application 
$zip = (get-item a.zip).fullname 
$folder = $app.namespace($zip) 
$item = new-item file.txt -itemtype file -value "Mooo" -force 
$folder.copyhere($item.fullname) 

para obtener el contenido de una cremallera utilizar este:

$zipfilename = "myzip.zip" 
$shellApplication = new-object -com shell.application 
$zipPackage = $shellApplication.NameSpace($zipfilename) 
$zipPackage.Items() | Select Path 
+0

Ejecuto mi script dos veces, la segunda vez que ejecuta la prueba.El archivo zip ya estará allí, pero los resultados son los mismos, aún estará vacío. Sin embargo, probé esto con los mismos resultados :-( –

+0

En mi caja (xp pro/powershell 2.0) funciona: crea un archivo myfile.zip y agrega un archivo.txt. –

+0

Creo que me malinterpretas. No quiero obtener el contenido sin comprimir del archivo zip después de crearlo. Quiero obtener el archivo zip real (comprimido) en el mismo script que lo creó, inmediatamente después de crear el archivo zip. Si ejecuta los dos scripts juntos como uno (ligeramente modificado para corregir el nombre del archivo comprimido), el resultado es el mismo: un archivo zip vacío. –

0

crea el archivo en un cierre, por lo que la variable se sale del ámbito y powershell cierra el archivo ... si convirtieras esa parte en una subrutina, entonces se habría cerrado naturalmente cuando regresaste.

new-item -type File test.zip -force 
{ 
    $zip = (get-item test.zip).fullname 
    $app = new-object -com shell.application 
    $folder = $app.namespace($zip) 
    $item = new-item file.txt -itemtype file -value "Mooo" -force 
    $folder.copyhere($item.fullname) 
} 
dir test.zip # <---- Empty test.zip file 
Get-Content -Encoding byte $zip 
+0

Intenté esto, pero la creación de un cierre o colocar el código en una función no mejora las cosas. –

1

Es posible que desee reconsiderar el uso de una biblioteca de terceros. Sin embargo, si debe utilizar CopyHere, intente esto:

new-item -type File test.zip -force 
$zip = (get-item test.zip).fullname 
$app = new-object -com shell.application 
$folder = $app.namespace($zip) 
$item = new-item file.txt -itemtype file -value "Mooo" -force 
$folder.copyhere($item.fullname) 
while($folder.Items().Item($item.Name) -Eq $null) 
{ 
    start-sleep -seconds 0.01 
    write-host "." -nonewline 
} 
dir test.zip # <---- Empty test.zip file 
Get-Content -Encoding byte $zip 
+0

Si uno tiene que usar el caparazón para crear archivos zip, entonces esta solución funciona bien para determinar cuándo se completa la copia asíncrona. No, todavía no estoy seguro de si este método dará como resultado una escritura parcial del archivo comprimido. –

1

También tuve este problema, todo lo que necesita es esperar hasta que no se haya completado la operación comprimir. Entonces, se me ocurre esta solución, debe colocar este código después de ejecutar el cmdlet "$ folder.copy aquí" o "copy-ToZip" de PowerPack.

$isCompleted = $false 
    $guid = [Guid]::NewGuid().ToString() 
    $tmpFileName = $zipFileName + $guid 
    # The main idea is to try to rename target ZIP file. If it success then archiving operation is complete. 
    while(!$isCompleted) 
    { 
     start-sleep -seconds 1 
     Rename-Item $zipFileName $tmpFileName -ea 0 #Try to rename with suppressing errors 
     if (Test-Path $tmpFileName) 
     { 
      Rename-Item $tmpFileName $zipFileName #Rename it back 
      $isCompleted = $true 
     } 
    } 
Cuestiones relacionadas