public static bool InstallSkin(string skinPackagePath) { try { using (ZipFile zip = new ZipFile(skinPackagePath)) { bool skinValid = false; foreach (ZipEntry entry in zip.Entries) { if (entry.FileName == "Configuration/config.xml") { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); skinValid = ValidateSkinConfigEntry(ms); } break; } } if (skinValid) { string skinDir = IO.Paths.SkinPath + Path.GetFileNameWithoutExtension(skinPackagePath); if (Directory.Exists(skinDir) == false) { Directory.CreateDirectory(skinDir); } zip.ExtractAll(skinDir, ExtractExistingFileAction.OverwriteSilently); return true; } else { return false; } } } catch { return false; } }
private static void Zip64SeekToCentralDirectory(ZipFile zf) { Stream s = zf.ReadStream; byte[] block = new byte[16]; // seek back to find the ZIP64 EoCD // I think this might not work for .NET CF ? s.Seek(-40, SeekOrigin.Current); s.Read(block, 0, 16); Int64 Offset64 = BitConverter.ToInt64(block, 8); // change for workitem 8098 s.Seek(Offset64, SeekOrigin.Begin); //zf.SeekFromOrigin(Offset64); uint datum = (uint)PMDCP.Compression.Zip.SharedUtilities.ReadInt(s); if (datum != ZipConstants.Zip64EndOfCentralDirectoryRecordSignature) throw new BadReadException(String.Format(" ZipFile::Read(): Bad signature (0x{0:X8}) looking for ZIP64 EoCD Record at position 0x{1:X8}", datum, s.Position)); s.Read(block, 0, 8); Int64 Size = BitConverter.ToInt64(block, 0); block = new byte[Size]; s.Read(block, 0, block.Length); Offset64 = BitConverter.ToInt64(block, 36); // change for workitem 8098 s.Seek(Offset64, SeekOrigin.Begin); //zf.SeekFromOrigin(Offset64); }
private static void ReadZipFileComment(ZipFile zf) { // read the comment here byte[] block = new byte[2]; zf.ReadStream.Read(block, 0, block.Length); Int16 commentLength = (short)(block[0] + block[1] * 256); if (commentLength > 0) { block = new byte[commentLength]; zf.ReadStream.Read(block, 0, block.Length); // workitem 6513 - only use UTF8 as necessary // test reflexivity string s1 = DefaultEncoding.GetString(block, 0, block.Length); byte[] b2 = DefaultEncoding.GetBytes(s1); if (BlocksAreEqual(block, b2)) { zf.Comment = s1; } else { // need alternate (non IBM437) encoding // workitem 6415 // use UTF8 if the caller hasn't already set a non-default encoding System.Text.Encoding e = (zf._provisionalAlternateEncoding.CodePage == 437) ? System.Text.Encoding.UTF8 : zf._provisionalAlternateEncoding; zf.Comment = e.GetString(block, 0, block.Length); } } }
// build the TOC by reading each entry in the file. private static void ReadIntoInstance_Orig(ZipFile zf) { zf.OnReadStarted(); //zf._entries = new System.Collections.Generic.List<ZipEntry>(); zf._entries = new System.Collections.Generic.Dictionary<String,ZipEntry>(); ZipEntry e; if (zf.Verbose) if (zf.Name == null) zf.StatusMessageTextWriter.WriteLine("Reading zip from stream..."); else zf.StatusMessageTextWriter.WriteLine("Reading zip {0}...", zf.Name); // work item 6647: PK00 (packed to removable disk) bool firstEntry = true; ZipContainer zc = new ZipContainer(zf); while ((e = ZipEntry.ReadEntry(zc, firstEntry)) != null) { if (zf.Verbose) zf.StatusMessageTextWriter.WriteLine(" {0}", e.FileName); zf._entries.Add(e.FileName,e); firstEntry = false; } // read the zipfile's central directory structure here. // workitem 9912 // But, because it may be corrupted, ignore errors. try { ZipEntry de; while ((de = ZipEntry.ReadDirEntry(zf)) != null) { // Housekeeping: Since ZipFile exposes ZipEntry elements in the enumerator, // we need to copy the comment that we grab from the ZipDirEntry // into the ZipEntry, so the application can access the comment. // Also since ZipEntry is used to Write zip files, we need to copy the // file attributes to the ZipEntry as appropriate. ZipEntry e1 = zf._entries[de.FileName]; if (e1 != null){ e1._Comment = de.Comment; if (de.IsDirectory) e1.MarkAsDirectory(); } } // workitem 8299 if (zf._locEndOfCDS > 0) zf.ReadStream.Seek(zf._locEndOfCDS, SeekOrigin.Begin); ReadCentralDirectoryFooter(zf); if (zf.Verbose && !String.IsNullOrEmpty(zf.Comment)) zf.StatusMessageTextWriter.WriteLine("Zip file Comment: {0}", zf.Comment); } catch { } zf.OnReadCompleted(); }
private static void ReadIntoInstance(ZipFile zf) { Stream s = zf.ReadStream; try { if (!s.CanSeek) { ReadIntoInstance_Orig(zf); return; } zf.OnReadStarted(); // change for workitem 8098 //zf._originPosition = s.Position; // Try reading the central directory, rather than scanning the file. uint datum = VerifyBeginningOfZipFile(s); if (datum == ZipConstants.EndOfCentralDirectorySignature) return; // start at the end of the file... // seek backwards a bit, then look for the EoCD signature. int nTries = 0; bool success = false; // The size of the end-of-central-directory-footer plus 2 bytes is 18. // This implies an archive comment length of 0. We'll add a margin of // safety and start "in front" of that, when looking for the // EndOfCentralDirectorySignature long posn = s.Length - 64; long maxSeekback = Math.Max(s.Length - 0x4000, 10); do { s.Seek(posn, SeekOrigin.Begin); long bytesRead = SharedUtilities.FindSignature(s, (int)ZipConstants.EndOfCentralDirectorySignature); if (bytesRead != -1) success = true; else { nTries++; // Weird: with NETCF, negative offsets from SeekOrigin.End DO // NOT WORK. So rather than seek a negative offset, we seek // from SeekOrigin.Begin using a smaller number. posn -= (32 * (nTries + 1) * nTries); // increasingly larger if (posn < 0) posn = 0; // BOF } } while (!success && posn > maxSeekback); if (success) { // workitem 8299 zf._locEndOfCDS = s.Position - 4; byte[] block = new byte[16]; s.Read(block, 0, block.Length); zf._diskNumberWithCd = BitConverter.ToUInt16(block, 2); if (zf._diskNumberWithCd == 0xFFFF) throw new ZipException("Spanned archives with more than 65534 segments are not supported at this time."); zf._diskNumberWithCd++; // I think the number in the file differs from reality by 1 int i = 12; uint offset32 = (uint) BitConverter.ToUInt32(block, i); if (offset32 == 0xFFFFFFFF) { Zip64SeekToCentralDirectory(zf); } else { // change for workitem 8098 s.Seek(offset32, SeekOrigin.Begin); } ReadCentralDirectory(zf); } else { // Could not find the central directory. // Fallback to the old method. // workitem 8098: ok //s.Seek(zf._originPosition, SeekOrigin.Begin); s.Seek(0L, SeekOrigin.Begin); ReadIntoInstance_Orig(zf); } } catch //(Exception e1) { if (zf._ReadStreamIsOurs && zf._readstream != null) { try { zf._readstream.Close(); #if !NETCF zf._readstream.Dispose(); #endif zf._readstream = null; } finally { } } throw; // new Ionic.Utils.Zip.ZipException("Exception while reading", e1); } // the instance has been read in zf._contentsChanged = false; }
private static void ReadCentralDirectoryFooter(ZipFile zf) { Stream s = zf.ReadStream; int signature = PMDCP.Compression.Zip.SharedUtilities.ReadSignature(s); byte[] block = null; int j = 0; if (signature == ZipConstants.Zip64EndOfCentralDirectoryRecordSignature) { // We have a ZIP64 EOCD // This data block is 4 bytes sig, 8 bytes size, 44 bytes fixed data, // followed by a variable-sized extension block. We have read the sig already. // 8 - datasize (64 bits) // 2 - version made by // 2 - version needed to extract // 4 - number of this disk // 4 - number of the disk with the start of the CD // 8 - total number of entries in the CD on this disk // 8 - total number of entries in the CD // 8 - size of the CD // 8 - offset of the CD // ----------------------- // 52 bytes block = new byte[8 + 44]; s.Read(block, 0, block.Length); Int64 DataSize = BitConverter.ToInt64(block, 0); // == 44 + the variable length if (DataSize < 44) throw new ZipException("Bad DataSize in the ZIP64 Central Directory."); zf._versionMadeBy = BitConverter.ToUInt16(block, j); j += 2; zf._versionNeededToExtract = BitConverter.ToUInt16(block, j); j += 2; zf._diskNumberWithCd = BitConverter.ToUInt32(block, j); j += 2; //zf._diskNumberWithCd++; // hack!! // read the extended block block = new byte[DataSize - 44]; s.Read(block, 0, block.Length); // discard the result signature = PMDCP.Compression.Zip.SharedUtilities.ReadSignature(s); if (signature != ZipConstants.Zip64EndOfCentralDirectoryLocatorSignature) throw new ZipException("Inconsistent metadata in the ZIP64 Central Directory."); block = new byte[16]; s.Read(block, 0, block.Length); // discard the result signature = PMDCP.Compression.Zip.SharedUtilities.ReadSignature(s); } // Throw if this is not a signature for "end of central directory record" // This is a sanity check. if (signature != ZipConstants.EndOfCentralDirectorySignature) { s.Seek(-4, SeekOrigin.Current); throw new BadReadException(String.Format("ZipFile::ReadCentralDirectoryFooter: Bad signature ({0:X8}) at position 0x{1:X8}", signature, s.Position)); } // read the End-of-Central-Directory-Record block = new byte[16]; zf.ReadStream.Read(block, 0, block.Length); // off sz data // ------------------------------------------------------- // 0 4 end of central dir signature (0x06054b50) // 4 2 number of this disk // 6 2 number of the disk with start of the central directory // 8 2 total number of entries in the central directory on this disk // 10 2 total number of entries in the central directory // 12 4 size of the central directory // 16 4 offset of start of central directory with respect to the starting disk number // 20 2 ZIP file comment length // 22 ?? ZIP file comment if (zf._diskNumberWithCd == 0) { zf._diskNumberWithCd = BitConverter.ToUInt16(block, 2); //zf._diskNumberWithCd++; // hack!! } // read the comment here ReadZipFileComment(zf); }
private static void ReadCentralDirectory(ZipFile zf) { // We must have the central directory footer record, in order to properly // read zip dir entries from the central directory. This because the logic // knows when to open a spanned file when the volume number for the central // directory differs from the volume number for the zip entry. The // _diskNumberWithCd was set when originally finding the offset for the // start of the Central Directory. // workitem 9214 bool inputUsesZip64 = false; ZipEntry de; while ((de = ZipEntry.ReadDirEntry(zf)) != null) { de.ResetDirEntry(); zf.OnReadEntry(true, null); if (zf.Verbose) zf.StatusMessageTextWriter.WriteLine("entry {0}", de.FileName); zf._entries.Add(de.FileName,de); // workitem 9214 if (de._InputUsesZip64) inputUsesZip64 = true; } // workitem 9214; auto-set the zip64 thing if (inputUsesZip64) zf.UseZip64WhenSaving = Zip64Option.Always; // workitem 8299 if (zf._locEndOfCDS > 0) zf.ReadStream.Seek(zf._locEndOfCDS, SeekOrigin.Begin); ReadCentralDirectoryFooter(zf); if (zf.Verbose && !String.IsNullOrEmpty(zf.Comment)) zf.StatusMessageTextWriter.WriteLine("Zip file Comment: {0}", zf.Comment); // We keep the read stream open after reading. if (zf.Verbose) zf.StatusMessageTextWriter.WriteLine("read in {0} entries.", zf._entries.Count); zf.OnReadCompleted(); }
/// <summary> /// A wrapper for <see cref="ZipFile.IsZipFile(string, bool)">ZipFile.IsZipFile(string, bool)</see> /// </summary> /// <remarks> /// We cannot use "overloaded" Method names in COM interop. /// So, here, we use a unique name. /// </remarks> /// <param name="filename">The filename to of the zip file to check.</param> /// <returns>true if the file contains a valid zip file.</returns> public bool IsZipFileWithExtract(string filename) { return(ZipFile.IsZipFile(filename, true)); }
/// <summary> /// Reads one entry from the zip directory structure in the zip file. /// </summary> /// <param name="zf"> /// The zipfile for which a directory entry will be read. From this param, the /// method gets the ReadStream and the expected text encoding /// (ProvisionalAlternateEncoding) which is used if the entry is not marked /// UTF-8. /// </param> /// <returns>the entry read from the archive.</returns> internal static ZipEntry ReadDirEntry(ZipFile zf) { System.IO.Stream s = zf.ReadStream; System.Text.Encoding expectedEncoding = zf.ProvisionalAlternateEncoding; int signature = PMDCP.Compression.Zip.SharedUtilities.ReadSignature(s); // return null if this is not a local file header signature if (IsNotValidZipDirEntrySig(signature)) { s.Seek(-4, System.IO.SeekOrigin.Current); // Getting "not a ZipDirEntry signature" here is not always wrong or an // error. This can happen when walking through a zipfile. After the // last ZipDirEntry, we expect to read an // EndOfCentralDirectorySignature. When we get this is how we know // we've reached the end of the central directory. if (signature != ZipConstants.EndOfCentralDirectorySignature && signature != ZipConstants.Zip64EndOfCentralDirectoryRecordSignature && signature != ZipConstants.ZipEntrySignature // workitem 8299 ) { throw new BadReadException(String.Format(" ZipEntry::ReadDirEntry(): Bad signature (0x{0:X8}) at position 0x{1:X8}", signature, s.Position)); } return null; } int bytesRead = 42 + 4; byte[] block = new byte[42]; int n = s.Read(block, 0, block.Length); if (n != block.Length) return null; int i = 0; ZipEntry zde = new ZipEntry(); zde._Source = ZipEntrySource.ZipFile; zde._container = new ZipContainer(zf); unchecked { zde._VersionMadeBy = (short)(block[i++] + block[i++] * 256); zde._VersionNeeded = (short)(block[i++] + block[i++] * 256); zde._BitField = (short)(block[i++] + block[i++] * 256); zde._CompressionMethod = (Int16)(block[i++] + block[i++] * 256); zde._TimeBlob = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; zde._LastModified = PMDCP.Compression.Zip.SharedUtilities.PackedToDateTime(zde._TimeBlob); zde._timestamp |= ZipEntryTimestamp.DOS; zde._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; zde._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256); zde._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256); } // preserve zde._CompressionMethod_FromZipFile = zde._CompressionMethod; zde._filenameLength = (short)(block[i++] + block[i++] * 256); zde._extraFieldLength = (short)(block[i++] + block[i++] * 256); zde._commentLength = (short)(block[i++] + block[i++] * 256); zde._diskNumber = (UInt32)(block[i++] + block[i++] * 256); zde._InternalFileAttrs = (short)(block[i++] + block[i++] * 256); zde._ExternalFileAttrs = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; zde._RelativeOffsetOfLocalHeader = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256); // workitem 7801 zde.IsText = ((zde._InternalFileAttrs & 0x01) == 0x01); block = new byte[zde._filenameLength]; n = s.Read(block, 0, block.Length); bytesRead += n; if ((zde._BitField & 0x0800) == 0x0800) { // UTF-8 is in use zde._FileNameInArchive = PMDCP.Compression.Zip.SharedUtilities.Utf8StringFromBuffer(block); } else { zde._FileNameInArchive = PMDCP.Compression.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding); } // Console.WriteLine("\nEntry : {0}", zde._LocalFileName); // Console.WriteLine(" V Madeby/Needed: 0x{0:X4} / 0x{1:X4}", zde._VersionMadeBy, zde._VersionNeeded); // Console.WriteLine(" BitField/Compression: 0x{0:X4} / 0x{1:X4}", zde._BitField, zde._CompressionMethod); // Console.WriteLine(" Lastmod: {0}", zde._LastModified.ToString("u")); // Console.WriteLine(" CRC: 0x{0:X8}", zde._Crc32); // Console.WriteLine(" Comp / Uncomp: 0x{0:X8} ({0}) 0x{1:X8} ({1})", zde._CompressedSize, zde._UncompressedSize); //zde._FileNameInArchive = zde._LocalFileName; if (zde.AttributesIndicateDirectory) zde.MarkAsDirectory(); // may append a slash to filename if nec. // workitem 6898 else if (zde._FileNameInArchive.EndsWith("/")) zde.MarkAsDirectory(); zde._CompressedFileDataSize = zde._CompressedSize; if ((zde._BitField & 0x01) == 0x01) { zde._Encryption_FromZipFile = zde._Encryption = EncryptionAlgorithm.PkzipWeak; // this may change after processing the Extra field zde._sourceIsEncrypted = true; } if (zde._extraFieldLength > 0) { zde._InputUsesZip64 = (zde._CompressedSize == 0xFFFFFFFF || zde._UncompressedSize == 0xFFFFFFFF || zde._RelativeOffsetOfLocalHeader == 0xFFFFFFFF); // Console.WriteLine(" Input uses Z64?: {0}", zde._InputUsesZip64); bytesRead += zde.ProcessExtraField(s, zde._extraFieldLength); zde._CompressedFileDataSize = zde._CompressedSize; } // we've processed the extra field, so we know the encryption method is set now. if (zde._Encryption == EncryptionAlgorithm.PkzipWeak) { // the "encryption header" of 12 bytes precedes the file data zde._CompressedFileDataSize -= 12; } #if AESCRYPTO else if (zde.Encryption == EncryptionAlgorithm.WinZipAes128 || zde.Encryption == EncryptionAlgorithm.WinZipAes256) { zde._CompressedFileDataSize = zde.CompressedSize - (ZipEntry.GetLengthOfCryptoHeaderBytes(zde.Encryption) + 10); zde._LengthOfTrailer = 10; } #endif // tally the trailing descriptor if ((zde._BitField & 0x0008) == 0x0008) { // sig, CRC, Comp and Uncomp sizes if (zde._InputUsesZip64) zde._LengthOfTrailer += 24; else zde._LengthOfTrailer += 16; } if (zde._commentLength > 0) { block = new byte[zde._commentLength]; n = s.Read(block, 0, block.Length); bytesRead += n; if ((zde._BitField & 0x0800) == 0x0800) { // UTF-8 is in use zde._Comment = PMDCP.Compression.Zip.SharedUtilities.Utf8StringFromBuffer(block); } else { zde._Comment = PMDCP.Compression.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding); } } //zde._LengthOfDirEntry = bytesRead; return zde; }
/// <summary> /// Rewrite the directory within a zipfile. /// </summary> /// /// <remarks> /// /// <para> /// In cases of data error, the directory in a zip file can get out of /// synch with the entries in the zip file. This method attempts to fix /// the zip file if this has occurred. /// </para> /// /// <para> This can take a long time for large zip files. </para> /// /// <para> This won't work if the zip file uses a non-standard /// code page - neither IBM437 nor UTF-8. </para> /// /// <para> /// This method is not supported in the Reduced or Compact Framework /// versions of DotNetZip. /// </para> /// /// <para> /// Developers using COM can use the <see /// cref="ComHelper.FixZipDirectory(String)">ComHelper.FixZipDirectory(String)</see> /// method. /// </para> /// /// </remarks> /// /// <param name="zipFileName">The filename to of the zip file to fix.</param> /// /// <seealso cref="CheckZip(string)"/> /// <seealso cref="CheckZip(string,bool,out System.Collections.ObjectModel.ReadOnlyCollection<String>)"/> public static void FixZipDirectory(string zipFileName) { using (var zip = new ZipFile()) { zip.FullScan = true; zip.Initialize(zipFileName); zip.Save(zipFileName); } }
/// <summary> /// Checks a zip file to see if its directory is consistent, /// and optionally fixes the directory if necessary. /// </summary> /// /// <remarks> /// /// <para> /// In cases of data error, the directory within a zip file can get out of /// synch with the entries in the zip file. This method checks the given /// zip file, and returns true if this has occurred. It also optionally /// fixes the zipfile, saving the fixed copy in <em>Name</em>_Fixed.zip. /// </para> /// /// <para> /// This method may take a long time to run for large zip files. It /// will take even longer if the file actually needs to be fixed, and if /// <c>fixIfNecessary</c> is true. /// </para> /// /// <para> /// This method is not supported in the Reduced or Compact /// Framework versions of DotNetZip. /// </para> /// /// </remarks> /// /// <param name="zipFileName">The filename to of the zip file to check.</param> /// /// <param name="fixIfNecessary">If true, the method will fix the zip file if /// necessary.</param> /// /// <param name="messages"> /// a collection of messages generated while checking, indicating any problems that are found. /// </param> /// /// <returns>true if the named zip is OK; false if the file needs to be fixed.</returns> /// /// <seealso cref="CheckZip(string)"/> /// <seealso cref="FixZipDirectory(string)"/> public static bool CheckZip(string zipFileName, bool fixIfNecessary, out System.Collections.ObjectModel.ReadOnlyCollection<String> messages) { List<String> notes = new List<String>(); ZipFile zip1 = null; ZipFile zip2 = null; bool isOk = true; try { zip1 = new ZipFile(); zip1.FullScan = true; zip1.Initialize(zipFileName); zip2 = ZipFile.Read(zipFileName); foreach (var e1 in zip1) { foreach (var e2 in zip2) { if (e1.FileName == e2.FileName) { if (e1._RelativeOffsetOfLocalHeader != e2._RelativeOffsetOfLocalHeader) { isOk = false; notes.Add(String.Format("{0}: mismatch in RelativeOffsetOfLocalHeader (0x{1:X16} != 0x{2:X16})", e1.FileName, e1._RelativeOffsetOfLocalHeader, e2._RelativeOffsetOfLocalHeader)); } if (e1._CompressedSize != e2._CompressedSize) { isOk = false; notes.Add(String.Format("{0}: mismatch in CompressedSize (0x{1:X16} != 0x{2:X16})", e1.FileName, e1._CompressedSize, e2._CompressedSize)); } if (e1._UncompressedSize != e2._UncompressedSize) { isOk = false; notes.Add(String.Format("{0}: mismatch in UncompressedSize (0x{1:X16} != 0x{2:X16})", e1.FileName, e1._UncompressedSize, e2._UncompressedSize)); } if (e1.CompressionMethod != e2.CompressionMethod) { isOk = false; notes.Add(String.Format("{0}: mismatch in CompressionMethod (0x{1:X4} != 0x{2:X4})", e1.FileName, e1.CompressionMethod, e2.CompressionMethod)); } if (e1.Crc != e2.Crc) { isOk = false; notes.Add(String.Format("{0}: mismatch in Crc32 (0x{1:X4} != 0x{2:X4})", e1.FileName, e1.Crc, e2.Crc)); } // found a match, so stop the inside loop break; } } } zip2.Dispose(); zip2 = null; if (!isOk && fixIfNecessary) { string newFileName = Path.GetFileNameWithoutExtension(zipFileName); newFileName = System.String.Format("{0}_fixed.zip", newFileName); zip1.Save(newFileName); } } finally { if (zip1 != null) zip1.Dispose(); if (zip2 != null) zip2.Dispose(); } messages = notes.AsReadOnly(); // may or may not be empty return isOk; }
/// <summary> /// A wrapper for <see cref="ZipFile.FixZipDirectory(string)">ZipFile.FixZipDirectory(string)</see> /// </summary> /// <param name="filename">The filename to of the zip file to fix.</param> public void FixZipDirectory(string filename) { ZipFile.FixZipDirectory(filename); }
/// <summary> /// A wrapper for <see cref="ZipFile.CheckZip(string)">ZipFile.CheckZip(string)</see> /// </summary> /// <param name="filename">The filename to of the zip file to check.</param> /// /// <returns>true if the named zip file checks OK. Otherwise, false. </returns> public bool CheckZip(string filename) { return(ZipFile.CheckZip(filename)); }
/// <summary> /// Reads a zip file archive using the specified text encoding, the specified /// TextWriter for status messages, and the specified ReadProgress event handler, /// and returns the instance. /// </summary> /// /// <param name="fileName"> /// The name of the zip archive to open. /// This can be a fully-qualified or relative pathname. /// </param> /// /// <param name="readProgress"> /// An event handler for Read operations. /// </param> /// /// <param name="statusMessageWriter"> /// The <c>System.IO.TextWriter</c> to use for writing verbose status messages /// during operations on the zip archive. A console application may wish to /// pass <c>System.Console.Out</c> to get messages on the Console. A graphical /// or headless application may wish to capture the messages in a different /// <c>TextWriter</c>, such as a <c>System.IO.StringWriter</c>. /// </param> /// /// <param name="encoding"> /// The <c>System.Text.Encoding</c> to use when reading in the zip archive. Be /// careful specifying the encoding. If the value you use here is not the same /// as the Encoding used when the zip archive was created (possibly by a /// different archiver) you will get unexpected results and possibly exceptions. /// </param> /// /// <returns>The instance read from the zip archive.</returns> /// public static ZipFile Read(string fileName, TextWriter statusMessageWriter, System.Text.Encoding encoding, EventHandler<ReadProgressEventArgs> readProgress) { ZipFile zf = new ZipFile(); zf.ProvisionalAlternateEncoding = encoding; zf._StatusMessageTextWriter = statusMessageWriter; zf._name = fileName; if (readProgress != null) zf.ReadProgress = readProgress; if (zf.Verbose) zf._StatusMessageTextWriter.WriteLine("reading from {0}...", fileName); ReadIntoInstance(zf); zf._fileAlreadyExists = true; return zf; }
/// <summary> /// Reads a zip archive from a byte array, using the given StatusMessageWriter and text Encoding. /// </summary> /// /// <remarks> /// <para> /// This method is useful when the data for the zipfile is contained in a byte /// array, for example when retrieving the data from a database or other /// non-filesystem store. /// </para> /// /// </remarks> /// /// <param name="buffer">the byte array containing the zip data.</param> /// /// <param name="statusMessageWriter"> /// The <c>System.IO.TextWriter</c> to which verbose status messages are written /// during operations on the <c>ZipFile</c>. For example, in a console /// application, System.Console.Out works, and will get a message for each entry /// added to the ZipFile. If the TextWriter is <c>null</c>, no verbose messages /// are written. /// </param> /// /// <param name="encoding"> /// The text encoding to use when reading entries that do not have the UTF-8 /// encoding bit set. Be careful specifying the encoding. If the value you use /// here is not the same as the Encoding used when the zip archive was created /// (possibly by a different archiver) you will get unexpected results and /// possibly exceptions. See the <see cref="ProvisionalAlternateEncoding"/> /// property for more information. /// </param> /// /// <returns> /// an instance of ZipFile. The name is set to <c>null</c> (<c>Nothing</c> in VB). /// </returns> /// public static ZipFile Read(byte[] buffer, TextWriter statusMessageWriter, System.Text.Encoding encoding) { ZipFile zf = new ZipFile(); zf._StatusMessageTextWriter = statusMessageWriter; zf._provisionalAlternateEncoding = encoding; zf._readstream = new MemoryStream(buffer); zf._ReadStreamIsOurs = true; if (zf.Verbose) zf._StatusMessageTextWriter.WriteLine("reading from byte[]..."); ReadIntoInstance(zf); return zf; }
/// <summary> /// Reads a zip archive from a stream, using the specified text Encoding, the /// specified TextWriter for status messages, /// and the specified ReadProgress event handler. /// </summary> /// /// <remarks> /// <para> /// Reading of zip content begins at the current position in the stream. This /// means if you have a stream that concatenates regular data and zip data, if /// you position the open, readable stream at the start of the zip data, you /// will be able to read the zip archive using this constructor, or any of the /// ZipFile constructors that accept a <see cref="System.IO.Stream" /> as /// input. Some examples of where this might be useful: the zip content is /// concatenated at the end of a regular EXE file, as some self-extracting /// archives do. (Note: SFX files produced by DotNetZip do not work this /// way). Another example might be a stream being read from a database, where /// the zip content is embedded within an aggregate stream of data. /// </para> /// </remarks> /// /// <param name="zipStream">the stream containing the zip data.</param> /// /// <param name="statusMessageWriter"> /// The <c>System.IO.TextWriter</c> to which verbose status messages are written /// during operations on the <c>ZipFile</c>. For example, in a console /// application, System.Console.Out works, and will get a message for each entry /// added to the ZipFile. If the TextWriter is <c>null</c>, no verbose messages /// are written. /// </param> /// /// <param name="encoding"> /// The text encoding to use when reading entries that do not have the UTF-8 /// encoding bit set. Be careful specifying the encoding. If the value you use /// here is not the same as the Encoding used when the zip archive was created /// (possibly by a different archiver) you will get unexpected results and /// possibly exceptions. See the <see cref="ProvisionalAlternateEncoding"/> /// property for more information. /// </param> /// /// <param name="readProgress"> /// An event handler for Read operations. /// </param> /// /// <returns>an instance of ZipFile</returns> public static ZipFile Read(Stream zipStream, TextWriter statusMessageWriter, System.Text.Encoding encoding, EventHandler<ReadProgressEventArgs> readProgress) { if (zipStream == null) throw new ArgumentException("The stream must be non-null", "zipStream"); ZipFile zf = new ZipFile(); zf._provisionalAlternateEncoding = encoding; if (readProgress != null) zf.ReadProgress += readProgress; zf._StatusMessageTextWriter = statusMessageWriter; zf._readstream = (zipStream.Position == 0L) ? zipStream : new OffsetStream(zipStream); zf._ReadStreamIsOurs = false; if (zf.Verbose) zf._StatusMessageTextWriter.WriteLine("reading from stream..."); ReadIntoInstance(zf); return zf; }
/// <summary> /// A wrapper for <see cref="ZipFile.IsZipFile(string)">ZipFile.IsZipFile(string)</see> /// </summary> /// <param name="filename">The filename to of the zip file to check.</param> /// <returns>true if the file contains a valid zip file.</returns> public bool IsZipFile(string filename) { return(ZipFile.IsZipFile(filename)); }