2011-04-12 112 views
7

,我有以下腳本到一個文件夾(文件夾中的所有文件)壓縮成一個zip文件:壓縮文件通過PS

set-content $zipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
$ZipFile = (new-object -com shell.application).NameSpace($zipFileName) 
Get-ChildItem $folder | foreach {$zipFile.CopyHere($_.fullname)} 

其中$文件夾=「C:\測試「和$ zipFileName =」C:\ data \ test.zip「爲例

它工作正常,如果」C:\ Test「不包含空的子文件夾,它似乎遞歸地壓縮sub中的所有文件-folders。我真的很喜歡簡單的線腳本。例如:

C:\Test 
    file1.dat 
    file2.dat 
    Test-Sub 
     File21.bat 
     .... 

但是,我在一個案例中出現錯誤。我發現如果有任何空文件夾如「C:\ Test \ EmptySub」,

C:\Test 
    file1.dat 
    file2.dat 
    Test-Sub 
     File21.bat 
     .... 
    EmptySub 
    AnotherSub 
     file31.sp1 
     ... 

該腳本會產生一個錯誤。我嘗試了以下腳本:

Get-ChildItem $files -Recurse | foreach { if (!$_.PSIsContainer) 
    {$zipFile.CopyHere($_.fullname)}} 

這不起作用。它只是跳過所有的子文件夾。不確定是否有過濾器或子句可跳過所有空的子文件夾?

更新:根據建議,我試了一下。我的問題沒有解決。這是我的問題的更新。首先,我更新了上面的腳本以顯示如何創建$ zipFile對象。其次我有建議代碼:

Get-ChildItem $files | ? {-not ($_.PSIsContainer -eq $True -and 
    $_.GetFiles().Count -eq 0) } | % {$zipfile.CopyHere($_.fullname)} 

我上面我的WindowsXP更新嘗試,它正常工作與空的子文件夾。但是,相同的代碼在Windows 2003 Server中不起作用。以下是錯誤消息:

[窗口標題] 壓縮(壓縮)文件夾錯誤

[內容] 未找到文件或沒有讀取權限。

[OK]

不知道這種類型的PK對象在Windows 2003服務器的工作原理,或者如果該對象的其他設置。

回答

3

您可以通過測試對來自GET-childitem空回檢測空目錄。例如,這將返回空目錄

dir | where{$_.PSIsContainer -and -not (gci $_)} 

雖然你的情況的列表,想要逆:

Get-ChildItem $files | where{-not ($_.PSIsContainer -and -not (gci $_))} | foreach {$zipfile.CopyHere($_.fullname)}} 
+0

它部分工作。在我的Q – 2011-04-13 21:30:33

2

您的代碼以您獲得任何種類的子項目(包括文件夾)的意義遞歸地工作。如果你的目的是爲了排除空文件夾,你應該進行篩選:

試試這個內膽:

 
gci $folder |` 
? {-not ($_.PSIsContainer -eq $True -and $_.GetFiles().Count -eq 0) } |` 
% {$zipfile.CopyHere($_.fullname)} 
1

這裏是我創建的zip文件的功能。你得到讀取錯誤的原因是因爲。CopyHere是一個異步複製過程,因此我的腳本在繼續下一個要壓縮的文件之前驗證文件是否存在於zip文件中:

function Out-ZipFile ([string]$path) 
{ 
    try 
    { 
     $files = $input 

     if ($path.StartsWith(".\")) { $path=$path.replace(".\","$($pwd)\") } 
     if (-not $path.Contains("\")) { $path="$($pwd)\$($path)" } 
     if (-not $path.EndsWith('.zip')) {$path += '.zip'} 

     if (-not (test-path $path)) { 
      set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
     } 

     $ZipFile = (new-object -com shell.application).NameSpace($path) 
     $files | % { 
      $FileName = $_.name 
      "Adding $FileName to $path"; 
      $ZipFile.CopyHere($_.fullname); 
      While (($ZipFile.Items() | where { $_.Name -like $FileName }).Size -lt 1) { Start-Sleep -m 100 }; 
     } 
    } 
    catch 
    { 
     write-output "Error Encountered: `n$_" 
     return $_ 
     throw 
    } 
} 
+0

中查看我的更新我喜歡管道,但由於某種原因,這個名字在我看來一直沒有解決。我最終在這裏使用for-each解決方案:https://superuser.com/questions/290461/powershell-zip-file-synchronously – 2018-02-27 17:18:43