2012-06-13 154 views
23

Tôi đang tạo tệp lược đồ cơ sở dữ liệu hàng đêm và muốn đặt tất cả các tệp được tạo mỗi đêm, một tệp cho mỗi cơ sở dữ liệu vào thư mục và nén thư mục đó. Tôi có một kịch bản lệnh PowerShell để tạo lược đồ. Chỉ tạo kịch bản lệnh của db và sau đó thêm tất cả các tệp vào một thư mục mới. Vấn đề nằm trong phần nén của quá trình này.Tạo thư mục nén/nén trong Windows bằng Powershell hoặc dòng lệnh

Có ai có bất kỳ ý tưởng nào nếu điều này có thể được thực hiện bằng tiện ích Windows được cài đặt sẵn có xử lý nén thư mục không? Nó sẽ là tốt nhất để sử dụng tiện ích đó nếu có thể hơn là một cái gì đó như 7zip (Tôi không cảm thấy như cài đặt 7zip trên máy chủ của mỗi khách hàng và nó có thể mất nhiều năm để làm điều đó nếu tôi yêu cầu họ).

+0

Tôi nghĩ điều này giải thích các tùy chọn của bạn: http://richardspowershellblog.wordpress.com/2007/06/02/powershell-and-compressed-files/ – David

+1

Cảm ơn bạn rất nhiều! Đây là một giải pháp sạch sẽ và dễ dàng. Chỉ đường cho bất kỳ ai khác có thể vấp ngã trên luồng này. Tải xuống các tiện ích mở rộng cộng đồng PowerShell từ: http://pscx.codeplex.com/downloads Trích xuất tệp rồi di chuyển thư mục đến: C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules. Sau đó, nhập khẩu mô-đun bằng cách chạy lệnh: Nhập-Mô-đun Pscx – TechDawg270

Trả lời

19

Dưới đây là một số chức năng liên quan đến zip không phụ thuộc vào tiện ích mở rộng: Compress Files with Windows PowerShell.

Chức năng chính mà bạn có thể muốn được quan tâm là:

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

Cách sử dụng:

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

Có một caveat: chức năng shell.application đối tượng của NameSpace() thất bại trong việc mở ra các file zip để viết nếu đường dẫn không tuyệt đối. Vì vậy, nếu bạn đã chuyển một đường dẫn tương đối đến Add-Zip, nó sẽ không thành công với lỗi rỗng, vì vậy đường dẫn đến tệp zip phải tuyệt đối.

Hoặc bạn chỉ có thể thêm $zipfilename = resolve-path $zipfilename vào đầu hàm.

+0

Điều này đã hiệu quả và tôi đánh giá cao phản hồi kịp thời, nhưng tôi nghĩ rằng tải xuống và cài đặt tiện ích mở rộng cộng đồng PowerShell và sự sẵn có của lệnh Write-Zip là sạch hơn/dễ dàng hơn phương pháp đạt được chức năng. – TechDawg270

+0

@ TechDawg270: Đồng ý - Tôi chủ yếu chỉ đăng nội dung này vì mục đích hoàn chỉnh. – voithos

3

này nén. \ Trong nội dung. \ Out.zip với System.IO.Packaging.ZipPackage theo gương các here

$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() 
1

Dùng câu trả lời voithos' để file zip lên trong PowerShell, chỉ có một vấn đề với chức năng Add-Zip, Start-sleep -milliseconds 500 gây ra vấn đề nếu tập tin không thể được nén hoàn toàn trong thời gian đó -> cái tiếp theo bắt đầu trước khi nó hoàn thành gây ra lỗi và một số tập tin không bị nén.

Vì vậy, sau khi chơi xung quanh một chút, đầu tiên cố gắng để có được một truy cập sẽ kiểm tra số lượng $ zipPackage.Items() và chỉ tiếp tục sau khi các mục đếm tăng (mà không hoạt động vì nó sẽ trở về 0 trong một số trường hợp khi nó không nên) Tôi thấy rằng nó sẽ trở về 0 nếu gói vẫn còn nén/sao chép các tập tin lên (tôi nghĩ rằng, haha). Thêm một vòng lặp đơn giản trong khi bắt đầu-ngủ bên trong của nó, chờ đợi cho các zipPackage.Items(). Đếm là một giá trị khác không trước khi tiếp tục và điều này dường như để giải quyết vấn đề.

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

Sử dụng PowerShell Phiên bản 3.0:

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

Hope this helps.

+4

Đây không phải là lệnh ghép ngắn PowerShell 3. –

21

Cách gốc với .NET 4 mới nhất.5 khuôn khổ, nhưng hoàn toàn tính năng ít:

Creation:

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

Extraction:

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

Như đã đề cập, hoàn toàn tính năng ít hơn, do đó, không mong đợi một ghi đè cờ.

+1

Đây là trang nhã. Có một upvote .. – deepelement

+0

Tôi đã truy cập đường dẫn bị từ chối với giải pháp này: (Bạn có ý tưởng để buộc rằng? – Jerome2606

+0

@ Jerome2606 ... sau đó làm cho đường dẫn của bạn có thể truy cập. Cũng như đã đề cập, "không mong đợi một lá cờ ghi đè" – sonjz

4

Kể từ PowersShell 5, có một lệnh ghép ngắn Compress-Archive thực hiện tác vụ đó.

Các vấn đề liên quan