public ZipOpener(BinaryData inputData, string password) { m_zip = new ZipWrapper(); m_zip.SetPassword(password); if (inputData.Length >= 85000) { m_fileName = Path.GetTempFileName(); inputData.Save(m_fileName); if (!m_zip.OpenZip(m_fileName)) { throw new System.Exception(m_zip.LastErrorText); } } else { using (Stream str = inputData.AsStream()) { byte[] data = StreamUtils.SafeButUnpleasantReadAllStreamIntoByteArray(str); if (!m_zip.OpenFromMemory(data)) { throw new System.Exception(m_zip.LastErrorText); } } } }
static public List<string> GetFileNames(string fileName, bool includeDirectorys) { Logger.LogInfo("Getting filesnames within: " + fileName); List<string> fileNames = new List<string>(); using (ZipWrapper zip = new ZipWrapper()) { if (!zip.OpenZip(fileName)) { Logger.LogDebug("Unable to open: " + fileName); throw new Exception("Unable to open Zip file:" + fileName); } int n = zip.NumEntries; Logger.LogInfo(string.Format("Zip contains [{0}] files", n.ToString())); Chilkat.ZipEntry entry; for (int i = 0; i <= n - 1; i++) { entry = zip.GetEntryByIndex(i); if (entry.IsDirectory && !includeDirectorys)//Skip over directories { continue; } fileNames.Add(entry.FileName); Logger.LogInfo("Zip contains file: " + entry.FileName); } } return fileNames; }
public ZipOpener(string filePath, string password) { m_zip = new ZipWrapper(); m_zip.SetPassword(password); //m_fileName = filePath; DON'T DO THIS! would result in the file being DELETED on Dispose(), not what we want if (!m_zip.OpenZip(filePath)) { throw new System.Exception(m_zip.LastErrorText); } }
/// <summary> /// Remove password from zip file /// </summary> /// <param name="fileName"></param> /// <param name="password"></param> /// <returns></returns> static public bool RemovePasswordFromZip(string fileName, string password) { // Poor mans version, extract entire zip and then read into a new one, but handles encrypted zips with empty folders in string tempDump = string.Empty; try { using (ZipWrapper zip = new ZipWrapper()) { zip.DecryptPassword = password; zip.OpenZip(fileName); tempDump = Path.Combine(Path.GetDirectoryName(fileName), Guid.NewGuid().ToString()); if (!zip.Extract(tempDump)) { Logger.LogError(zip.LastErrorText); throw new Exception(string.Format("Unable to extract {0] to {1}", fileName, tempDump)); } zip.CloseZip(); } System.IO.File.Delete(fileName); // Remove the original encrypted file // Now create a new zip without a password using (ZipWrapper zipDecrypted = new ZipWrapper()) { zipDecrypted.AppendFiles(tempDump, true); zipDecrypted.FileName = fileName; if (!zipDecrypted.WriteZipAndClose()) // Create a new decrypted zip { Logger.LogError(zipDecrypted.LastErrorText); throw new Exception("Failed trying to create decrypted version of: " + fileName); } } } finally { ForceDeleteDirectory(tempDump); } return true; //// Chilkat seems to have an issue with passworded zips containing empty folders, once password is removed(using below procedure that they outline in their samples //// http://www.example-code.com/csharp/zip_RemoveZipEncryption.asp) errors occur when trying to use the decrypted zip //// //// Also it seems to have issues with complex nesting, missing/not seeing files below the root after decryption //using (Chilkat.Zip zip = new Chilkat.Zip()) //{ // zip.UnlockComponent(Chilkat_Serial); // zip.DecryptPassword = password; // if (!zip.OpenZip(fileName)) // { // Logger.LogDebug("Unable to open: " + fileName); // Logger.LogDebug(zip.LastErrorText); // return false; // } // zip.Encryption = 0; // zip.PasswordProtect = false; // string tmpFile = Path.Combine(Path.GetDirectoryName(fileName), Guid.NewGuid().ToString() + ".zip"); // zip.FileName = tmpFile; // // From Chilkat:: // // Write the unencrypted .zip // // What happens during WriteZipAndClose? -- // // The encrypted entries from myEncrypted.zip are streamed in, // // decrypted, and then written out directly into unencrypted.zip // // In other words, internally the component is smart enough // // to stream the data from the existing .zip to the new .zip // // automatically, decrypting in the process.. // if (zip.WriteZipAndClose()) // { // Logger.LogInfo("Saved unpassworded zip to: " + tmpFile); // System.IO.File.Copy(tmpFile, fileName, true); // Logger.LogInfo("Copied: " + tmpFile + " back to: " + fileName); // System.IO.File.Delete(tmpFile); // return true; // } // else // { // Logger.LogDebug("Unable to decrypt: " + fileName); // Logger.LogDebug(zip.LastErrorText); // return false; // } //} }
static public bool ZipHasPassword(string filePath) { try { using (ZipWrapper zip = new ZipWrapper()) { zip.OpenZip(filePath); Logger.LogInfo(string.Format("File {0} PasswordProtect status: {1}", filePath, zip.PasswordProtect.ToString())); Logger.LogInfo(string.Format("File {0} Encryption value: {1}", filePath, zip.Encryption.ToString())); // PasswordProtect == old style zip 2.0 encryption // Encryption > 0 indicates 'modern' strong encryption has been used return zip.PasswordProtect || (zip.Encryption > 0); } } catch (Exception ex) { Logger.LogDebug(ex); throw new Exception("Unable to process zip file:" + filePath); } }
/// <summary> /// Assumes no inital password /// </summary> /// <param name="fileName"></param> /// <param name="password"></param> /// <param name="encryption"></param> /// <param name="encryptionKeyLength"></param> /// <returns></returns> static public bool AddPasswordToZip(string fileName, string password, string encryption, string encryptionKeyLength) { if (VerifyPassword(fileName, password)) { return true; } using(var zip = new ZipWrapper()) { zip.OpenZip(fileName); zip.Encryption = 0; if (!string.IsNullOrEmpty(encryption)) // 'modern' zip encryption being used { try { zip.EncryptKeyLength = 128; if (!string.IsNullOrEmpty(encryptionKeyLength)) { zip.EncryptKeyLength = System.Convert.ToInt32(encryptionKeyLength); } zip.Encryption = System.Convert.ToInt32(encryption); } catch (FormatException) { zip.Encryption = 0; zip.EncryptKeyLength = 0; } } if (zip.Encryption == 0) // zip 2.0 encryption { zip.PasswordProtect = true; } zip.EncryptPassword = password; if (!zip.WriteZipAndClose()) { Logger.LogError(zip.LastErrorText); throw new Exception(String.Format("Failed adding password to zip {0}", fileName)); } return true; } }
public bool PackContainer(Collection<IContainer> fileList, FileData filedata, Dictionary<string, string> properties, string baseFileName, string sPassword) { filedata.Password = sPassword; string outputFileName = Path.GetTempFileName(); try { using (ZipWrapper zip = new ZipWrapper()) { zip.SetCompressionLevel(9); // max compression zip.FileName = outputFileName; zip.TempDir = Path.GetDirectoryName(outputFileName); // To zip using utf-8 filenames, set the OemCodePage = 65001 zip.OemCodePage = 65001; if (filedata.Password != null && 0 < filedata.Password.Length) { string sEncryption = string.Empty; string sEncryptionKeyLength = string.Empty; zip.Encryption = 0; if (properties.TryGetValue("Encryption", out sEncryption)) { try { zip.EncryptKeyLength = 128; if (properties.TryGetValue("EncryptionKeyLength", out sEncryptionKeyLength)) zip.EncryptKeyLength = System.Convert.ToInt32(sEncryptionKeyLength); zip.Encryption = System.Convert.ToInt32(sEncryption); } catch (FormatException) { zip.Encryption = 0; zip.EncryptKeyLength = 0; } } if (zip.Encryption == 0) zip.PasswordProtect = true; zip.SetPassword(filedata.Password); } // Get the folders in, first for (int i = 0; i < fileList.Count; ++i) { IFile zipEntry = fileList[i] as IFile; if (null == zipEntry) { Logger.LogError("Unable to convert IContainer to IFile file because underlying type was " + fileList[i].GetType()); continue; } if (zipEntry.FileType == FileType.Folder) // Just create the folder { zip.AppendOneFileOrDir(zipEntry.DisplayName, false); } } // And then the files for (int i = 0; i < fileList.Count; ++i) { IFile zipEntry = fileList[i] as IFile; if (null == zipEntry) { Logger.LogError("Unable to convert IContainer to IFile file because underlying type was " + fileList[i].GetType()); continue; } if (zipEntry.FileType == FileType.Folder) // Skip the folders as we have already created them. { continue; } // Which parts of the path do we NOT want to put into the zip folder structure string ignorePath = zipEntry.FileName.ToLower().Replace(zipEntry.DisplayName.ToLower(), ""); // This is needed if you right click on a unicode .docx file name -> Send to Mail Recipient // because outlook converts it into 8.3 file format filename so the display name is different from the file name. string displayName = Path.Combine(Path.GetDirectoryName(zipEntry.DisplayName), Path.GetFileName(zipEntry.FileName)); if (!ignorePath.EndsWith("\\")) { ignorePath = ignorePath.Substring(0, ignorePath.LastIndexOf("\\") + 1); } zip.AppendFromDir = ignorePath; zip.AppendOneFileOrDir(displayName, true /*We want to recreate folders within the zip files*/); } if (!zip.WriteZipAndClose()) { Logger.LogError(zip.LastErrorText); throw new Exception(String.Format("Failed trying pack container {0}, temp version of {1} ", outputFileName, baseFileName)); } // Now replace the orig zip with our new temp one System.IO.File.Copy(outputFileName, baseFileName, true); } filedata.BinaryFileData = new OptimizedBinaryData(outputFileName); return true; } catch (Exception ex) { Logger.LogError(ex.Message); throw ex; } finally { // Delete the temp zip we built System.IO.File.Delete(outputFileName); // Give the Chilkat zip object chance to finish with the files, otherwise we can get a locked file exception later when we try to delete the temp files System.GC.Collect(); System.GC.WaitForPendingFinalizers(); } }
private string CreateDuplicateName(ZipWrapper zip, string filename) { if (string.IsNullOrEmpty(filename)) return string.Empty; using (Chilkat.ZipEntry zipEntry = zip.GetEntryByName(filename)) { if (null == zipEntry) return filename; } StringBuilder newFilename; if (filename.Contains("(") && filename.Contains(")")) { int startIndex = filename.LastIndexOf('(') + 1; int endIndex = filename.IndexOf(')', startIndex); if (-1 != endIndex) { string stringValue = filename.Substring(startIndex, endIndex - startIndex); int count; if (ConvertToInt(stringValue, out count)) { count++; newFilename = new StringBuilder(filename.Substring(0, startIndex)); newFilename.Append(Convert.ToString(count)); newFilename.Append(filename.Substring(endIndex)); return CreateDuplicateName(zip, newFilename.ToString()); } } } newFilename = new StringBuilder(Path.GetFileNameWithoutExtension(filename)); newFilename.Append("(1)"); newFilename.Append(Path.GetExtension(filename)); return CreateDuplicateName(zip, newFilename.ToString()); }