// This function virtually expands the representation of a newly created zip // with file content already existing on disk. This is especially for the case // where the Zip Action creates zips for each document, but the zip IFile is not // in the expanded state. This method associates the zip with it's files. public Collection<IContainer> AssociateContainerWithExistingFiles(FileData fileData, string password, GetExistingFileContentIdDelegate getExistingFileContentId) { try { fileData.Password = password; // Setting the status back to false. Next call may be with correct password. fileData.FileEncrypted = false; fileData.ReadPasswordProtected = false; // For this association operation to succeed the zip file should already exist. if (!System.IO.File.Exists(fileData.Filename)) { throw new FileNotFoundException( "The zip should already exist.", fileData.Filename); } Collection<IContainer> fileList = new Collection<IContainer>(); Logger.LogDebug(string.Format("Opening zip file \"{0}\".", fileData.Filename)); using (ZipOpener zo = new ZipOpener(fileData.Filename, password)) { ZipWrapper zip = zo.Zip; // For each entry in the zip, ask the GetExistingFileContentId delegate for the existing file's content ID. for (int index = 0; index < zip.NumEntries; ++index) { Logger.LogDebug(string.Format("Zip entry {0}.", index)); using (Chilkat.ZipEntry zipEntry = zip.GetEntryByIndex(index)) { if (zipEntry == null) { Logger.LogDebug("Zip entry is null."); break; } // Try to get file path and content ID. string contentId, filePath; if (!getExistingFileContentId(zipEntry.FileName, out contentId, out filePath)) { throw new KeyNotFoundException(string.Format("Couldn't find the content item relating to the file \"{0}\".", zipEntry.FileName)); } Logger.LogDebug(string.Format("Adding file \"{0}\".", filePath)); IFile file = new File(filePath, zipEntry.FileName, contentId); fileList.Add(file); } } } Logger.LogDebug("Completed zip container to existing files association."); return fileList; } catch (Exception ex) { Logger.LogError(ex); fileData.FileEncrypted = true; fileData.ReadPasswordProtected = true; return null; } }
public Collection<IContainer> ExpandContainer(FileData filedata, string sPassword) { try { filedata.Password = sPassword; // Setting the status back to false. Next call may be with correct password. filedata.FileEncrypted = false; filedata.ReadPasswordProtected = false; Collection<IContainer> fileList = new Collection<IContainer>(); using (ZipOpener zo = new ZipOpener(filedata.BinaryFileData, sPassword)) { ZipWrapper zip = zo.Zip; zip.TempDir = System.IO.Path.GetTempPath(); // If the zip contents are encrypted this will // throw an exception and set the encryption flags // in the catch block below. for (int index = 0; index < zip.NumEntries; ++index) { using (Chilkat.ZipEntry zipEntry = zip.GetEntryByIndex(index)) { if (null == zipEntry) break; if (zipEntry.IsDirectory) continue; byte[] entryData = zipEntry.Inflate(); if (entryData == null || (entryData.Length == 0 && !IsZeroLengthFile(zipEntry)) // we don't want to mistakenly report zips containing zero length files as encrypted, so don't throw! ) { throw new Exception(zip.LastErrorText); } using (MemoryStream streamOut = new MemoryStream(entryData)) { IFile file = new File(streamOut, zipEntry.FileName); fileList.Add(file); } } } } return fileList; } catch (System.Exception ex) { Logger.LogDebug(ex); filedata.FileEncrypted = true; filedata.ReadPasswordProtected = true; return null; } }
// Extract the contents to tempfiles public Collection<IContainer> ExpandContainerToDisk(FileData filedata, string sPassword) { try { if (!System.IO.File.Exists(filedata.Filename)) { throw new Exception("File does not exist: " + filedata.Filename); } filedata.Password = sPassword; // Setting the status back to false. Next call may be with correct password. filedata.FileEncrypted = false; filedata.ReadPasswordProtected = false; var rootPath = Path.Combine(Path.GetTempPath(), "Workshare"); Collection<IContainer> fileList = new Collection<IContainer>(); using (ZipOpener zo = new ZipOpener(filedata.Filename, sPassword)) { ZipWrapper zip = zo.Zip; // If the zip contents are encrypted this will // throw an exception and set the encryption flags // in the catch block below. for (int index = 0; index < zip.NumEntries; ++index) { using (Chilkat.ZipEntry zipEntry = zip.GetEntryByIndex(index)) { if (null == zipEntry) break; var lfm = new LocalCopyOfFileManager(true, Path.Combine(rootPath, Guid.NewGuid().ToString())); m_resources.Add(lfm); var path = lfm.ManagedFolder; var displayName = zipEntry.FileName; var fileName = Path.Combine(path, displayName); try { // If the proposed path + file name is to long we need to get the binary content of the zip entry and write it out to a file. if (fileName.Length > TempFileController.MAX_FULLY_QUALIFIED_NAME) { // If the ZipEntry is in a sub folder the folder name will be prepended to the 'ZipEntry.FileName' property e.g. 'Folder1\Folder2\Test.docx'. // The destination path should include any sub folders derived from the 'zipEntry.FileName' property. // We exclude file name when deriving the path because Path.GetFullPath or Path.GetDirectoryName will throw if path + file name long. path = Path.Combine(path, Path.GetDirectoryName(zipEntry.FileName)); Directory.CreateDirectory(path); displayName = Path.GetFileName(zipEntry.FileName); fileName = Path.Combine(path, TempFileController.GetShortFilename(path, displayName)); fileList.Add(CreateFileFromContent(zipEntry, fileName)); } else { // Extract the zip entry to the given location. fileList.Add(ExtractAttributedFile(zipEntry, path)); } } catch (Exception) { if (zip != null && !String.IsNullOrEmpty(zip.LastErrorText)) { Logger.LogError("Error in Zip" + zip.LastErrorText); } throw; } } } } return fileList; } catch (System.Exception ex) { Logger.LogError(ex); filedata.FileEncrypted = true; filedata.ReadPasswordProtected = true; return null; } }