Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell - How to complete/close a zip file in powershell

Tags:

powershell

zip

I want to create a zip file in powershell, add items to the zip file, then get the compressed content of that zip file as bytes immediately after the zip file is created, in the same scipt. The problem is that it does not seem that the zip application has written its contents to the file system. How does one close/flush the zip application so that the next powershell statement can gain access to the newly created zip file?

Example:

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

The "dir test.zip" shows a zip file with no contents, thus the Get-Content returns nothing.

Please note that this seems to be a problem with the asynchronous behavior of the copyhere action. If I sleep after the copyhere line, the zip file will become populated. However, I do not know how long one must sleep, nor do I want to delay the processing.

Much Thanks in advance!

like image 452
Eric Vasilik Avatar asked Nov 05 '22 06:11

Eric Vasilik


2 Answers

You might want to reconsider using a third party library. However, if you must use copyhere, try this:

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 
like image 164
jon Z Avatar answered Nov 09 '22 13:11

jon Z


I also had this problem, all that you need is to wait until zipping operation is not completed. So, i come up with this solution, you should place this code after executing "$folder.copyhere" or "Copy-ToZip" powerpack cmdlet.

    $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
        }
    }
like image 35
megaboich Avatar answered Nov 09 '22 13:11

megaboich