From PS to Zip

Dziś zaprezentuję jak przy pomocy PowerShella można zarządzać plikami Zip. Wbrew pozorom jest to bardzo prosty zabieg składający się z trzech etapów:

  1. Stworzenia pliku z odpowiednim nagłówkiem (o ile już nie istnieje)
  2. Otwarcia tego pliku
  3. Skopiowania zawartości

Ad 1) W celu stworzenia naszego pliku zip posłużymy się standardową komendą Set-Content, dzięki której wpisujemy nagłówek pliku:

$zipfile = <ścieżka do nie istniejącego narazie pliku zip>
Set-Content zipfile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))

Ad 2) Wykorzystujemy klasę Microsoft COM (Component Object Model) Shell.Application w celu odpowiedniego otwarcia pliku:

$shellApplication = New-Object -ComObject Shell.Application
$zipPackage = $shellApplication.NameSpace($zipfile)

Ad 3)Wykorzystując metodę CopyHere obiektu zipPackage kopiujemy zawartość interesujących nas plików do paczki zip:

$file = <ścieżka do interesującego nas pliku>
$zipPackage.CopyHere($file)

W wielkim skrócie to tyle. Poniżej jednak przedstawię gotowe funkcję, które wykorzystuję gdy zajdzie potrzeba pracy z plikami zip. W szczególności przydatne na maszynach w wersji Core, gdzie nie ma dostępu do explorera aby móc coś wypakować lub spakować.

Pierwsza funkcja pozwala nam na spakowanie pliku lub zbioru plików, zarówno podanych jako parametr albo poprzez tak zwanego pipelina, czyli przekazując parametry z polecenia do polecenia przy użyciu znaku „|”.

Function Add-Zip
{
  param
  (
    [array]$files,
    [string]$zipfile
  )

  if(-not (Test-Path ($zipfile)))
  {
    Set-Content $zipfile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
  }

  $zip = dir $zipfile
  $zip.IsReadOnly = $false
  $zipfile = $zip.FullName

  $shellApplication = New-Object -ComObject Shell.Application
  $zipPackage = $shellApplication.NameSpace($zipfile)

  if($files)
  {
    Foreach($file in $files)
    {
      $zipPackage.CopyHere($file)
      Start-sleep -milliseconds 500
    }
  }

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

#Przykład:
dir * | Add-Zip -zipfile Test.zip
Add-Zip -files "p:\test2.txt" -zipfile Test.zip
Add-Zip -files "p:\test3.txt","p:\test3.ps1" -zipfile Test.zip

Druga prezentowana funkcja pozwala na podejrzenie zawartości pliku zip.

Function Get-Zip
{
  param([string]$zipfile)
  if(Test-Path($zipfile))
  {
    $zip = dir $zipfile
    $zipfile = $zip.FullName

    $shellApplication = New-Object -ComObject shell.application
    $zipPackage = $shellApplication.NameSpace($zipfile)
    $zipPackage.Items() | Select Name, ModifyDate, Size
  }
}

#Przykład:
Get-Zip Test.zip

Ostatnia dość istotna funkcja to wypakowanie naszego pliku zip.

Function Extract-Zip
{
  param
  (
    [string]$zipfile,
    [string]$destination
  )

  if(Test-Path($zipfile))
  {
    $zip = dir $zipfile
    $zipfile = $zip.FullName

    $shellApplication = New-Object -ComObject shell.application
    $zipPackage = $shellApplication.NameSpace($zipfile)

    if(-not (Test-Path($destination)))
    {
      $destination = (New-Item -Path $destination -Type directory).FullName
    }

    $destinationFolder = $shellApplication.NameSpace($destination)
    $destinationFolder.CopyHere($zipPackage.Items())
  }
}

#Przykład:
Extract-Zip Test.zip P:\test2

Oczywiście w celu ułatwienia możemy sobie całość zapisać do jednego pliku .ps1 i gdy przyjdzie taka potrzeba importować go jak zwykły moduł.

Import-Module <ścieżka do naszego pliku zip.ps1>

Źródła:
http://msdn.microsoft.com/en-us/library/bb774094(v=vs.85).aspx
http://www.fileformat.info/format/zip/corion.htm
http://www.pkware.com/documents/casestudies/APPNOTE.TXT

Reklamy

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s