Introduction
This Helps Class allows to obtain a Raw Collection of Entries from ZipArchive with no Path Checking.
Later, you can use selected valid entries to deflate or rename or whatever you want.
Background
ZipArchive has a public property called Entries as single access to all entries (filenames and directories) contained in a Zip file.
But, ZipArchive user internaly System.IO.Path.CheckInvalidPathChars agains all entries before return the entries collection.
When we are working against Mac or Linux created Zip files those entries can have ".DS_Store" o similar names not valid in windows for historical reasons.
In those cases. ZipArchive fails without alternatives.
Using the code
This simple extension, add a GetRawEntries() method to avoid this problem.
public static class ZipArchiveHelper
{
private static FieldInfo _Entries;
private static MethodInfo _EnsureDirRead;
static ZipArchiveHelper()
{
_Entries= typeof(ZipArchive).GetField("_entries",BindingFlags.NonPublic|BindingFlags.Instance);
_EnsureDirRead = typeof(ZipArchive).GetMethod("EnsureCentralDirectoryRead", BindingFlags.NonPublic | BindingFlags.Instance);
}
public static List<ZipArchiveEntry> GetRawEntries(this ZipArchive archive)
{
_EnsureDirRead.Invoke(archive, null);
return (List<ZipArchiveEntry>)_Entries.GetValue(archive);
}
}
Points of Interest
"Private Static FieldInfo _Entries" is a variable stored once at startup. So, there are no performance impact using this code.
All Zip Entries into ZipArchive exists before the "Entries" Call. It simply exposes all entries whit an extra Path checking (Just the checking we want avoid).
History
This problem is here for years, especially non-English developers and/or Linux/Mac native Zip Files.
Update: Add "EnsureCentralDirectoryRead" before extract entries.