23

毎晩データベーススキーマファイルを作成していますが、毎晩作成されるすべてのファイルをデータベースごとに1つずつフォルダーに入れ、そのフォルダーを圧縮したいと思います。スキーマを作成するPowerShellスクリプトがあります。データベースの作成スクリプトのみを作成し、すべてのファイルを新しいフォルダーに追加します。問題は、このプロセスの圧縮部分にあります。

フォルダ圧縮を処理するプリインストールされたWindowsユーティリティでこれを実現できるかどうか誰かが知っていますか?

可能であれば、7zipのようなものではなく、そのユーティリティを使用するのが最善です(すべての顧客のサーバーに7zipをインストールする気はなく、顧客に依頼すると、ITでインストールするのに何年もかかる場合があります)。

4

6 に答える 6

23

最新の.NET4.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") ;

前述のように、完全に機能がないため、上書きフラグを期待しないでください。

于 2014-06-11T21:25:30.020 に答える
20

拡張機能に依存しないzip関連の関数を次に示します。WindowsPowerShellを使用したファイルの圧縮

興味があると思われる主な機能は次のとおりです。

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

注意点が1つあります。パスが絶対パスでない場合、shell.applicationオブジェクトのNameSpace()関数は書き込み用にzipファイルを開くことができません。したがって、に相対パスを渡した場合Add-Zip、nullエラーで失敗するため、zipファイルへのパスは絶対パスである必要があります。

$zipfilename = resolve-path $zipfilenameまたは、関数の先頭にを追加することもできます。

于 2012-06-13T19:58:11.340 に答える
8

PowersShell 5の時点で、箱から出してタスクを実行するCompress-Archiveコマンドレットがあります。

于 2016-04-08T06:40:27.170 に答える
2

これにより、次の例に従って、System.IO.Packaging.ZipPackageを使用して。\inの内容が。\out.zipに圧縮されます

$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()
于 2012-10-19T16:39:26.450 に答える
2

PowerShellでファイルを圧縮するためにvoithosの回答を使用しましたが、Add-Zip機能に1つの問題がありました。その間にファイルを完全に圧縮できなかった場合、Start-sleep-milliseconds500が問題を引き起こしました->次のファイルの開始完了する前にエラーが発生し、一部のファイルが圧縮されませんでした。

したがって、少し遊んだ後、最初に$ zipPackage.Items()のカウントをチェックするカウンターを取得しようとし、アイテムのカウントが増加した後にのみ続行します(これは、場合によっては0を返すため機能しませんでしたパッケージがまだファイルを圧縮/コピーしている場合は0が返されることがわかりました(ハハ)。start-sleepを内部に持つ単純なwhileループを追加し、zipPackage.Items()。countがゼロ以外の値になるのを待ってから続行します。これにより、問題が解決したようです。

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)
}
}
于 2013-07-17T22:26:09.103 に答える
-3

PowerShellバージョン3.0の使用:

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

お役に立てれば。

于 2013-07-29T23:30:29.910 に答える