简体   繁体   English

Powershell - 如何在PowerShell中完成/关闭zip文件

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

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. 我想在powershell中创建一个zip文件,将项目添加到zip文件,然后在创建zip文件后立即将该zip文件的压缩内容作为字节,在同一个scipt中。 The problem is that it does not seem that the zip application has written its contents to the file system. 问题是,zip应用程序似乎没有将其内容写入文件系统。 How does one close/flush the zip application so that the next powershell statement can gain access to the newly created zip file? 如何关闭/刷新zip应用程序,以便下一个powershell语句可以访问新创建的zip文件?

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. “dir test.zip”显示没有内容的zip文件,因此Get-Content不返回任何内容。

Please note that this seems to be a problem with the asynchronous behavior of the copyhere action. 请注意,这似乎是copyhere操作的异步行为的问题。 If I sleep after the copyhere line, the zip file will become populated. 如果我在copyhere行之后睡觉,zip文件将被填充。 However, I do not know how long one must sleep, nor do I want to delay the processing. 但是,我不知道必须睡多久,也不想延迟处理。

Much Thanks in advance! 非常感谢提前!

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. 所以,我想出了这个解决方案,你应该在执行“$ folder.copyhere”或“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
        }
    }

You might want to reconsider using a third party library. 您可能想重新考虑使用第三方库。 However, if you must use copyhere , try this: 但是,如果您必须使用copyhere ,请尝试以下操作:

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 

try creating the zip empty file like this: 尝试创建这样的zip空文件:

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

Then the rest of your code. 然后是你的其余代码。

this code in my box works: 我的方框中的代码有效:

$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 )

to get the content of a zip use this: 获取zip的内容使用此:

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

Create the file in a closure, so that the variable goes out of scope and powershell closes the file... if you'd made that part into a subroutine then it would have closed naturally when you returned. 在闭包中创建文件,以便变量超出范围并且powershell关闭文件...如果您将该部分放入子例程中,那么当您返回时它将自然关闭。

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

This method to zip files is not appropriate for automated scripts. 压缩文件的这种方法不适用于自动脚本。 This has limitations in Windows 2003 and Windows xp server for 3 gigs. 这在3台演出的Windows 2003和Windows xp服务器中有局限性。 Also, it does not give proper errors. 此外,它没有给出正确的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM