2012-02-09 57 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 
     } 
    }