PowerShell : Compress files with Windows an improved version
English
When I am looking for a way to compress file(s) into Zip, I find a blog from David Aiken here (Compress Files with Windows PowerShell then package a Windows Vista Sidebar Gadget) . I will just focus on Add-Zip function and nothing more.
Here is the original code:
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
}
}
usage: dir c:\\demo\\files\\\*.\* -Recurse | add-Zip c:\\demo\\myzip.zip
I am raising two problems with the code:
1. Looking at the usage example, it is clear that the function accept only fully path filename. The reason, on line-12 , the $shellApplication.NameSpace parameter is $zipfilename; and this is not possible without giving fully path filename.
2. On line-16, the operation expect that $input array will contains object with FullName properties, that why the usage example uses DIR. What about if you just want to specify a filename?
With the 2 problem above, I am ready to improve that function. In the new improved version, Get-ChildItem will help us to convert any string representation of a file to a fully path filename. It won’t break DIR piping functionality, since actually Get-ChildItem is dir (and extra) functionality.
Here is the improved version:
function Add-Zip
{
param(\[string\]$zipfilename)
$currFile = $zipfilename | get-childitem
if(-not (test-path($zipfilename)))
{
set-content $currFile.FullName ("PK" + \[char\]5 + \[char\]6 + ("$(\[char\]0)" \* 18))
(dir $currFile.FullName).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($currFile.Fullname)
$input | % {
$file = $\_ | get-childitem
$zipPackage.CopyHere($file.FullName)
Start-sleep -milliseconds 500
}
}
usage: "FileInThisFolder.txt" -Recurse | add-Zip "ZipInThisFolder.zip"
dir c:\\demo\\files\\\*.\* -Recurse | add-Zip c:\\demo\\myzip.zip
So, I hope you enjoy the improved version.