/*public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, IProgress<ZipProgress> progress) * { * ExtractToDirectory(source, destinationDirectoryName, progress, overwrite: false); * }*/ 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: var di = Directory.CreateDirectory(destinationDirectoryName); var destinationDirectoryFullPath = di.FullName; var count = 0; foreach (var entry in source.Entries) { count++; var 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); } } }
private void Report(object sender, ZipProgress zipProgress) { var percentCompleted = zipProgress.Processed * 100 / zipProgress.Total; _zipExtractor.ReportProgress(percentCompleted); }