I have a bunch of ZIP files that are in desperate need of some hierarchical reorganization and extraction. What I can do, currently, is create the directory structure and move the zip files to the proper location. The mystic cheese that I am missing is the part that extracts the files from the ZIP archive.
I have seen the MSDN articles on the ZipArchive
class and understand them reasonable well. I have also seen the VBScript ways to extract. This is not a complex class so extracting stuff should be pretty simple. In fact, it works "mostly". I have included my current code below for reference.
using (ZipPackage package = (ZipPackage)Package.Open(@"..\..\test.zip", FileMode.Open, FileAccess.Read))
{
PackagePartCollection packageParts = package.GetParts();
foreach (PackageRelationship relation in packageParts)
{
//Do Stuff but never gets here since packageParts is empty.
}
}
The problem seems to be somewhere in the GetParts
(or GetAnything for that matter). It seems that the package, while open, is empty. Digging deeper the debugger shows that the private member _zipArchive shows that it actually has parts. Parts with the right names and everything. Why won't the GetParts
function retrieve them? I'ver tried casting the open to a ZipArchive and that didn't help. Grrr.
I agree withe Cheeso. System.IO.Packaging is awkward when handling generic zip files, seeing as it was designed for Office Open XML documents. I'd suggest using DotNetZip or SharpZipLib
From "ZipPackage Class" (MSDN):
If you are manipulating ZIP files, you may want to look into a 3rd-party library to help you.
For example, DotNetZip, which has been recently updated. The current version is now v1.8. Here's an example to create a zip:
Here's an example to update an existing zip; you don't need to extract the files to do it:
here's an example that extracts entries:
DotNetZip supports multi-byte chars in filenames, Zip encryption, AES encryption, streams, Unicode, self-extracting archives. Also does ZIP64, for file lengths greater than 0xFFFFFFFF, or for archives with more than 65535 entries.
free. open source
get it at codeplex or direct download from windows.net - CodePlex has been discontinued and archived
(This is basically a rephrasing of this answer)
Turns out that
System.IO.Packaging.ZipPackage
doesn't support PKZIP, that's why when you open a "generic" ZIP file no "parts" are returned. This class only supports some specific flavor of ZIP files (see comments at the bottom of MSDN description) used among other as Windows Azure service packages up to SDK 1.6 - that's why if you unpack a service package and then repack it using say Info-ZIP packer it will become invalid.From MSDN,
In this sample, the Package class is used (as opposed to the ZipPackage.) Having worked with both, I've only seen flakiness happen when there's corruption in the zip file. Not necessarily corruption that throws the Windows extractor or Winzip, but something that the Packaging components have trouble handling.
Hope this helps, maybe it can provide you an alternative to debugging the issue.
I was having the exact same problem! To get the GetParts() method to return something, I had to add the [Content_Types].xml file to the root of the archive with a "Default" node for every file extension included. Once I added this (just using Windows Explorer), my code was able to read and extract the archived contents.
More information on the [Content_Types].xml file can be found here:
http://msdn.microsoft.com/en-us/magazine/cc163372.aspx - There is an example file below Figure 13 of the article.
Note: this code uses the Stream.CopyTo method in .NET 4.0