Сжатие файлов в папке, чтобы zip-файл с помощью PS - PullRequest
7 голосов
/ 13 апреля 2011

У меня есть следующие сценарии для сжатия папки (все файлы в папке) в zip-файл:

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

где $ folder = "C: \ Test" и $ zipFileName = "C: \ data \ test.zip "в качестве примера

Это прекрасно работает, если" C: \ Test "не содержит пустых подпапок, и кажется, что работает рекурсивно для сжатия всех файлов в подпапках.Мне очень нравится выше простой сценарий линии.Например:

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 ]

3 голосов
/ 13 апреля 2011

Вы можете обнаружить пустые каталоги, протестировав пустой возврат из get-childitem. Например, это вернет список пустых каталогов

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

Хотя в вашем случае вы хотите обратное:

Get-ChildItem $files | where{-not ($_.PSIsContainer -and -not (gci $_))} | foreach {$zipfile.CopyHere($_.fullname)}} 
2 голосов
/ 13 апреля 2011

Ваш код работает рекурсивно в том смысле, что вы получаете любой вид дочернего элемента (включая папки). Если вы намерены исключить пустую папку, вы должны отфильтровать их:

Попробуйте этот лайнер:

gci $folder |`
? {-not ($_.PSIsContainer -eq $True -and $_.GetFiles().Count -eq 0) } |`
% {$zipfile.CopyHere($_.fullname)}
1 голос
/ 18 июля 2013

Вот функция, которую я создал для архивирования файлов. Причина, по которой вы получаете ошибку чтения, заключается в том, что .CopyHere является процессом асинхронного копирования, поэтому мой сценарий проверяет, существует ли файл в zip-файле, прежде чем перейти к следующему файлу 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...