public async Task ExtractContainerAsync(string outputDirecotry, IProgress <double> progress = null, CancellationToken cancellationToken = default) { if (!Directory.Exists(outputDirecotry)) { _ = Directory.CreateDirectory(outputDirecotry); } PackagePartCollection parts = _package.GetParts(); int index = 0; int count = parts.Count(); Progress <double> innerProgress = new Progress <double> { }; innerProgress.ProgressChanged += (o, e) => { double percent = (index + e) / count; progress.Report(percent); }; if (progress == null) { innerProgress = null; } foreach (PackagePart part in parts) { if (cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); } string name = part.Uri.ToString(); string path = IOUtility.CombinePath(outputDirecotry, name); using FileStream fs = File.OpenWrite(path); await GetAsync(name, fs, innerProgress); index++; } }
public static int ExtractFiles(string packagefile, string destFolder) { //extract the package content to temp folder string tempfolder = Path.Combine(destFolder, Path.GetFileNameWithoutExtension(packagefile)); // Path.GetFileNameWithoutExtension(fileFullPath) if (Directory.Exists(tempfolder)) { Directory.Delete(tempfolder, true); //Wait till folder is deleted Thread.Sleep(1000); } Directory.CreateDirectory(tempfolder); try { using (System.IO.Packaging.Package ABpackage = System.IO.Packaging.Package.Open(@packagefile, FileMode.Open, FileAccess.Read, FileShare.Read)) { PackageRelationshipCollection relationships = ABpackage.GetRelationships(); PackagePartCollection parts = ABpackage.GetParts(); List <ZipEntry> files = GetPackageFile(packagefile); if (files.Count() - 1 != parts.Count()) //[Content_Types].xml is not considered as file part { if (files.Count() - 1 > parts.Count()) { Console.WriteLine(String.Format("Package {0} is corrupt. Additional files found", packagefile)); return(-1); } else if (files.Count() - 1 < parts.Count()) { Console.WriteLine(String.Format("Package {0} is corrupt. Some files are missing", packagefile)); return(-1); } } List <PackagePart> originalParts = new List <PackagePart>(); foreach (PackagePart item in parts) { if ((item.ContentType == "application/vnd.openxmlformats-package.relationships+xml") || (item.ContentType == "application/vnd.openxmlformats-package.digital-signature-origin") || (item.ContentType == "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) { } else { originalParts.Add(item); } } //if (originalParts.Count != relationships.Count() - 1) //{ // if (originalParts.Count > relationships.Count() - 1) // { // // ErrorBase.WriteToLog(String.Format("Package {0} is corrupt. Additional files found", packagefile)); // return -1; // } // else if (originalParts.Count > relationships.Count() - 1) // { // //ErrorBase.WriteToLog(String.Format("Package {0} is corrupt. Some files are missing", packagefile)); // return -1; // } //} foreach (PackageRelationship rel in relationships) { PackagePart packagePart = ABpackage.GetPart(rel.TargetUri); if (!packagePart.ContentType.Contains("part/")) { continue; } string lastModified = String.Empty; ZipEntry entry = files.Find(e => e.Name.Equals(packagePart.Uri.ToString().TrimStart('/'), StringComparison.InvariantCultureIgnoreCase)); if (entry == null) { continue; } //prepare file path information string partRelativePath = Uri.UnescapeDataString(packagePart.Uri.ToString()); //partRelativePath = (partRelativePath.TrimStart('/')).Replace("%20", " "); //partRelativePath = partRelativePath.Replace("%7b", "{"); //partRelativePath = partRelativePath.Replace("%7d", "}"); //partRelativePath = partRelativePath.Replace("%7B", "{"); //partRelativePath = partRelativePath.Replace("%7D", "}"); //partRelativePath = partRelativePath.Replace("%C2%A0", " "); //partRelativePath = partRelativePath.Replace("%C3%84", "Ä"); //partRelativePath = partRelativePath.Replace("%C3%A4", "ä"); //partRelativePath = partRelativePath.Replace("%C3%96", "Ö"); //partRelativePath = partRelativePath.Replace("%C3%B6", "ö"); //partRelativePath = partRelativePath.Replace("%C3%9C", "Ü"); //partRelativePath = partRelativePath.Replace("%C3%BC", "ü"); //partRelativePath = partRelativePath.Replace("%C3%9F", "ß"); //partRelativePath = partRelativePath.Replace("/", "\\"); string absolutePath = Path.Combine(tempfolder, partRelativePath.TrimStart('/')); if (!Directory.Exists(Path.GetDirectoryName(absolutePath))) { Directory.CreateDirectory(Path.GetDirectoryName(absolutePath)); } FileInfo extractFileInfo = new FileInfo(absolutePath); //Hp --> Logic: Check if the zip entry is older than the file system version //if yes don't overwrite the file system version. if ((extractFileInfo.Exists) && (DateTime.Compare(extractFileInfo.LastWriteTime, entry.DateTime) >= 0)) { continue; } // Create the file with the Part content using (FileStream fileStream = new FileStream(absolutePath, FileMode.Create)) { //ErrorBase.WriteToLog("Extracting file: " + absolutePath); try { packagePart.GetStream().CopyTo(fileStream); } catch (Exception ex) { //ErrorBase.WriteToLog(ex.Message); return(1); } } extractFileInfo.Refresh(); //Hp --> Always remove ReadOnly file attribute extractFileInfo.Attributes &= ~FileAttributes.ReadOnly; //set creation and modification date to zipped file date extractFileInfo.CreationTime = entry.DateTime; extractFileInfo.LastWriteTime = entry.DateTime; } } return(1); } catch (Exception ex) { //ErrorBase.WriteToLog(packagefile + "extraction encountered an exception." + ex.Message); //ErrorBase.WriteToLog("Cleanup extracted files / folders..."); if (Directory.Exists(tempfolder)) { Directory.Delete(tempfolder, true); //Wait till folder is deleted Thread.Sleep(1000); } return(-1); } }