public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, IProgress <ZipProgress> progress, bool overwrite) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (destinationDirectoryName == null) { throw new ArgumentNullException(nameof(destinationDirectoryName)); } // Rely on Directory.CreateDirectory for validation of destinationDirectoryName. // Note that this will give us a good DirectoryInfo even if destinationDirectoryName exists: DirectoryInfo di = Directory.CreateDirectory(destinationDirectoryName); string destinationDirectoryFullPath = di.FullName; int count = 0; foreach (ZipArchiveEntry entry in source.Entries) { count++; string fileDestinationPath = Path.GetFullPath(Path.Combine(destinationDirectoryFullPath, entry.FullName)); if (!fileDestinationPath.StartsWith(destinationDirectoryFullPath, StringComparison.OrdinalIgnoreCase)) { throw new IOException("File is extracting to outside of the folder specified."); } var zipProgress = new ZipProgress(source.Entries.Count, count, entry.FullName); progress.Report(zipProgress); if (Path.GetFileName(fileDestinationPath).Length == 0) { // If it is a directory: if (entry.Length != 0) { throw new IOException("Directory entry with data."); } Directory.CreateDirectory(fileDestinationPath); } else { // If it is a file: // Create containing directory: Directory.CreateDirectory(Path.GetDirectoryName(fileDestinationPath)); entry.ExtractToFile(fileDestinationPath, overwrite: overwrite); } } }
private void ZipProgress_ProgressChanged(object sender, ZipProgress e) { ProgressIntervalDetails = e.CurrentItem; ProgressIntervalPercent = (int)Math.Round((double)e.Processed / (double)e.Total); }