Подтвердить что ты не робот

Создание сжатой/сжатой папки в Windows с использованием Powershell или командной строки

Я создаю ночной файл схемы базы данных и хотел бы поместить все файлы, созданные каждую ночь, по одной для каждой базы данных, в папку и сжать эту папку. У меня есть PowerShell script, который создает schema.Only создание script из db, а затем добавляет все файлы в новую папку. Проблема заключается в части сжатия этого процесса.

Кто-нибудь знает, может ли это быть выполнено с предустановленной утилитой Windows, которая обрабатывает сжатие папки?

Лучше всего использовать эту утилиту, если это возможно, а не что-то вроде 7zip (мне не хочется устанавливать 7zip на каждый сервер клиентов, и, если я их попрошу, может потребоваться IT-годы).

4b9b3361

Ответ 1

Вот несколько связанных с zip функций, которые не зависят от расширений: Сжатие файлов с Windows PowerShell.

Основная функция, которая вам интересна, это:

function Add-Zip
{
    param([string]$zipfilename)

    if(-not (test-path($zipfilename)))
    {
        set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
        (dir $zipfilename).IsReadOnly = $false  
    }

    $shellApplication = new-object -com shell.application
    $zipPackage = $shellApplication.NameSpace($zipfilename)

    foreach($file in $input) 
    { 
            $zipPackage.CopyHere($file.FullName)
            Start-sleep -milliseconds 500
    }
}

Использование:

dir c:\demo\files\*.* -Recurse | Add-Zip c:\demo\myzip.zip

Существует одна оговорка: функция shell.application object NameSpace() не может открыть файл zip для записи, если путь не является абсолютным. Итак, если вы передали относительный путь к Add-Zip, он завершится с нулевой ошибкой, поэтому путь к zip файлу должен быть абсолютным.

Или вы можете просто добавить $zipfilename = resolve-path $zipfilename в начале функции.

Ответ 2

Натуральный способ с последней платформой .NET 4.5, но полностью не имеющий значения:

Создание:

Add-Type -Assembly "System.IO.Compression.FileSystem" ;
[System.IO.Compression.ZipFile]::CreateFromDirectory("c:\your\directory\to\compress", "yourfile.zip") ;

Экстракция:

Add-Type -Assembly "System.IO.Compression.FileSystem" ;
[System.IO.Compression.ZipFile]::ExtractToDirectory("yourfile.zip", "c:\your\destination") ;

Как уже упоминалось, полностью нет, поэтому не ожидайте флаг перезаписи.

Ответ 3

По состоянию на PowersShell 5 есть командлет Compress-Archive, который делает задачу из коробки.

Ответ 4

Это сжимает. \in содержимое в. \out.zip с помощью System.IO.Packaging.ZipPackage, следующего примеру здесь

$zipArchive = $pwd.path + "\out.zip"
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, [System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")
$in = gci .\in | select -expand fullName
[array]$files = $in -replace "C:","" -replace "\\","/"
ForEach ($file In $files) {
   $partName=New-Object System.Uri($file, [System.UriKind]"Relative")
   $part=$ZipPackage.CreatePart($partName, "application/zip", [System.IO.Packaging.CompressionOption]"Maximum")
   $bytes=[System.IO.File]::ReadAllBytes($file)
   $stream=$part.GetStream()
   $stream.Write($bytes, 0, $bytes.Length)
   $stream.Close()
                                                    }
$ZipPackage.Close()

Ответ 5

Используемый ответ voithos на zip файлы в PowerShell, только что имел одну проблему с функцией Add-Zip, Start-sleep -milliseconds 500 вызвал проблемы, если файл не мог быть полностью заархивирован за это время → следующий запуск до того, как он был завершен, вызвал ошибки, а некоторые файлы не были заархивированы.

Итак, немного поиграв, сначала попытаюсь получить счетчик, проверяющий счетчик $zipPackage.Items() и продолжая только после увеличения количества элементов (что не срабатывало, так как оно возвращало 0 в некоторых случаи, когда это не должно быть), я обнаружил, что он вернет 0, если пакет все еще застегивает/копирует файлы (я думаю, ха-ха). Добавлен простой цикл while со стартовым сном внутри него, ожидая, пока индекс zipPackage.Items() не будет равен нулю, прежде чем продолжить, и это, похоже, решит проблему.

function Add-Zip
{
param([string]$zipfilename)

if(-not (test-path($zipfilename)))
{
    set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
    (dir $zipfilename).IsReadOnly = $false  
}

$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)

foreach($file in $input) 
{ 
        $zipPackage.CopyHere($file.FullName)
        do
        {
            Start-sleep -milliseconds 250
        }
        while ($zipPackage.Items().count -eq 0)
}
}

Ответ 6

Использование PowerShell версии 3.0:

Copy-ToZip -File ".\blah" -ZipFile ".\blah.zip" -Force

Надеюсь, что это поможет.