public static void ZipFile(List<string> files, string strZipFileName, ZipCompressionLevels compression, bool appendZipContents) { if (files.Count == 0) { return; } string tempFolder = Path.Combine(Path.GetTempPath(), "SlyceTempZip"); if (Directory.Exists(tempFolder)) { DeleteDirectoryBrute(tempFolder); Directory.CreateDirectory(tempFolder); // Maybe the OS or anti-virus app denies access to the new // folder for a while, so let's give it a chance to do its thing. Thread.Sleep(50); } if (appendZipContents && File.Exists(strZipFileName)) { using (Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(strZipFileName)) { zip.CompressionLevel = ConvertCompressionLevel(compression); DeleteDirectoryBrute(tempFolder); Directory.CreateDirectory(tempFolder); try { // Unzip to temp folder zip.ExtractAll(tempFolder); } catch (Exception) { // Sometimes, for unknown reasons we get access denied exceptions DeleteDirectoryBrute(tempFolder); Directory.CreateDirectory(tempFolder); // Maybe the OS or anti-virus app denies access to the new // folder for a while, so let's give it a chance to do its thing. Thread.Sleep(1000); zip.ExtractAll(tempFolder); } // Delete the current Zip file try { DeleteFileBrute(strZipFileName); } catch (UnauthorizedAccessException) { if (File.Exists(strZipFileName) && (File.GetAttributes(strZipFileName) & FileAttributes.ReadOnly) != 0) { MessageBox.Show("Cannot save because file is readonly: " + strZipFileName, "Cannot Save - ReadOnly", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show("Zip failed due to locked files. Try adding [" + tempFolder + "] to the exclusion list in your anti-virus application.", "Cannot Zip - Locked Files", MessageBoxButtons.OK, MessageBoxIcon.Error); } throw; } } } // Copy all new files to the temp folder, deleting existing file if it exists foreach (string file in files) { string newFile = Path.Combine(tempFolder, Path.GetFileName(file)); DeleteFileBrute(newFile); try { File.Copy(file, newFile, true); } catch (Exception) { // Sometimes, for some reason the temp directory doesn't exist, // and checking for its existence on the line above doesn't help either! if (!Directory.Exists(tempFolder)) { Directory.CreateDirectory(tempFolder); // Maybe the OS or anti-virus app denies access to the new // folder for a while, so let's give it a chance to do its thing. Thread.Sleep(1000); File.Copy(file, newFile, true); } else { throw; } } } // Zip to a new file, not over any existing file. We will copy over the top if we are successful string tempZipFilename = Path.Combine(Path.GetDirectoryName(strZipFileName), "~" + Path.GetFileName(strZipFileName)); using (ZipFile targetZip = new ZipFile(tempZipFilename)) { targetZip.CompressionLevel = ConvertCompressionLevel(compression); // This adds all of the files in tempFolder to the root of the zip file. targetZip.AddDirectory(tempFolder); try { targetZip.Save(tempZipFilename); // Delete existing file if (File.Exists(strZipFileName)) { DeleteFileBrute(strZipFileName); } File.Move(tempZipFilename, strZipFileName); } catch (Exception) { int numTries = 0; bool success = false; Exception innerEx = null; while (!success && numTries < 10) { numTries++; // Maybe the OS or anti-virus app denies access to the new // folder for a while, so let's give it a chance to do its thing. Thread.Sleep(500); try { targetZip.Save(tempZipFilename); success = true; } catch (Exception ex2) { innerEx = ex2; } } if (!success) { if (File.Exists(strZipFileName) && (File.GetAttributes(strZipFileName) & FileAttributes.ReadOnly) != 0) { MessageBox.Show("Cannot save because file is readonly: " + strZipFileName, "Cannot Save - ReadOnly", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show( "Zip failed due to locked files. Try adding [" + tempFolder + "] to the exclusion list in your anti-virus application.", "Cannot Zip - Locked Files", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (innerEx != null) { throw innerEx; } else { throw; } } else { // Delete existing file if (File.Exists(strZipFileName)) { DeleteFileBrute(strZipFileName); } File.Move(tempZipFilename, strZipFileName); } } } }
private static CompressionLevel ConvertCompressionLevel(ZipCompressionLevels compression) { return (CompressionLevel)Enum.Parse(typeof(CompressionLevel), compression.ToString(), true); }
public static void ZipFile(List<string> files, string strZipFileName, ZipCompressionLevels compression) { ZipFile(files, strZipFileName, compression, true); }