2012-02-09 60 views
5

我想在powershell中創建一個zip文件,將項目添加到zip文件中,然後在創建zip文件後立即獲取該zip文件的壓縮內容作爲字節,在同一個scipt。問題在於,它似乎並未將zip應用程序的內容寫入文件系統。如何關閉/清空zip應用程序,以便下一個powershell語句可以訪問新創建的zip文件?Powershell - 如何在powershell中完成/關閉zip文件

例子:

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 

的 「DIR test.zip」 表示沒有內容的zip文件,從而獲取內容回報什麼。

請注意,這似乎是copyhere動作異步行爲的問題。如果我在copyhere行之後休息,則zip文件將被填充。但是,我不知道睡了多久,也不想推遲處理。

非常感謝提前!

+0

我從來沒有從PowerShell創建存檔,但這看起來不像它可以工作。 – Joey 2012-02-09 12:58:57

+1

看看這裏:http://dotnetzip.codeplex.com/。 Inoic.zip更適合使用zip文件! – 2012-02-09 13:01:09

+0

它確實有效。如果你看看你執行這些語句的目錄,你會發現已經創建了一個test.zip文件。 – 2012-02-09 13:01:24

回答

0

這種方法來壓縮文件不適合自動化腳本。這在Windows 2003和Windows xp服務器上有3個演出的限制。此外,它不會給出適當的錯誤。

+0

經過了一段時間,我不得不同意。調用shell來操縱zip需要很多開銷,並且是非常間接的。我查看了@Christian提到的Inoic.zip庫,並發現它對我的用例非常有效,它可以創建zip文件字節而不必寫入文件系統。 我感謝他們的創意解決方案! – 2012-02-10 11:15:45

+0

-DV根本沒有答案...... – GoClimbColorado 2013-12-10 06:27:34

0

嘗試創建ZIP空文件是這樣的:

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

那麼你的代碼的其餘部分。

這個代碼在我的機器上工作:

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

得到一個zip的內容使用:

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

我你運行我的腳本兩次,第二次運行測試。zip文件已經存在,但結果是一樣的 - 它仍然是空的。 無論如何,我試着用相同的結果:-( – 2012-02-09 13:13:35

+0

在我的包裝盒中(xp pro/powershell 2.0)工作原理:創建一個myfile.zip並添加一個file.txt – 2012-02-09 13:18:09

+0

我想你誤會了我。在創建zip文件後,我不想獲取壓縮文件的未壓縮內容,我想在創建壓縮文件的同一腳本中獲取實際的zip文件本身(壓縮),如果您運行兩個腳本(稍作修改以更正zip文件名),結果是相同的 - 一個空的zip文件 – 2012-02-09 13:31:52

0

創建一個封閉的文件,使變量超出範圍並且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 
+0

我試過這個,但是創建一個閉包或者將代碼放在一個函數中並不會改進。 – 2012-02-09 13:24:37

1

您可能想重新考慮使用第三方庫。但是,如果必須使用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 
+0

如果你必須使用shell來創建zip文件,那麼此解決方案可以很好地確定異步版本何時完成。不,我仍然不確定這種方法是否會導致部分寫入zip文件。 – 2012-02-10 11:18:09

1

我也有這個問題,所有你需要的是等待,直到拉鍊操作沒有完成。所以,我想出了這個解決方案,您應該在執行「$ 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 
     } 
    }