назад к списку статей

C# 7-zip Пример использования 7-zip в .Net

C# 7zipМногие .Net разработчики в своих проектах сталкиваются с задачей архивирования файлов. Наилучшие показатели по сжатию на текущий момент принадлежат архиватору 7-zip. Поэтому именно его будем использовать для сжатия файлов в наших .Net приложениях. К тому же он бесплатный :)

Последнюю версию 7-zip можно загрузить здесь.

Мы будем использовать 7-zip, запуская его с помощью ProcessStartInfo из сборки System.Diagnostics. Этот класс позволяет задавать набор аргументов командной строки при запуске процесса.

7-zip после своей работы может вернуть одно из следующих значений:

  • 0 – без ошибок;
  • 1 - некритичное предупреждение. Например, один или несколько файлов заблокированы другим процессом. 7-zip отработает, но эти файлы положит в архив в несжатом виде;
  • 2 – Фатальная ошибка;
  • 7 - Ошибка в командной строке;
  • 8 - Недостаточно памяти для выполнения операции;
  • 255 - Пользователь отменил выполнение операции.

В нашем C# проекте будем отлавливать код завершения 7-zip. Если операция архивирования или извлечения из архива прошла неудачно, то дадим 7-zip еще одну попытку выполнить операцию. Ну, если уж со второго раза ничего не получилось, нужно дать знать об этом программисту, вызвав исключение с текстом ошибки.

C# 7-zip добавление в архив

Логика работы функции по добавлению файлов в 7-zip архив AddToArchive:

  1. Проверяем наличие архиватора 7-zip;
  2. Формируем экземпляр класса ProcessStartInfo, задаем в качестве аргументов степень сжатия, список сжимаемых файлов, имя выходного архива. Для списка файлов можно применить маску файлов, используя стандартные dos-овские обозначения (*) и (?);
  3. Запускаем процесс 7-zip с нашими аргументами;
  4. По завершению анализируем код завершения ExitCode;
  5. Если нет критических ошибок, то заканчиваем работу;
  6. Иначе через одну секунду пробуем еще раз выполнить архивацию;
  7. При повторной неудаче генерируем исключение в зависимости от кода завершения ExitCode.

                        
using System.Diagnostics;
                        
/// <summary>
 /// Создает архив archiveName , содержащий файлы fileNames
 /// </summary>
 /// <param name="archiver">файл архиватора вместе с полным путем</param>
 /// <param name="fileNames">Файлы для запаковки (можно с маской *)</param>
 /// <param name="archiveName">Имя архива с полным путем</param>
 public static void AddToArchive(string archiver, string fileNames,
string archiveName)
 {
  try
  {
    // Предварительные проверки
    if (!File.Exists(archiver)) 
      throw new Exception("Архиватор 7z по пути \"" + archiver +
      "\" не найден");
 
    // Формируем параметры вызова 7z
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.FileName = archiver;
    // добавить в архив с максимальным сжатием
    startInfo.Arguments = " a -mx9 "; 
    // имя архива 
    startInfo.Arguments += "\"" + archiveName + "\""; 
    // файлы для запаковки
    startInfo.Arguments += " \"" + fileNames + "\""; 
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    int sevenZipExitCode = 0;
    using (Process sevenZip = Process.Start(startInfo))
    {
      sevenZip.WaitForExit();
      sevenZipExitCode = sevenZip.ExitCode;
    }
    // Если с первого раза не получилось, 
    //пробуем еще раз через 1 секунду
    if (sevenZipExitCode != 0 && sevenZipExitCode != 1)
    {
      using (Process sevenZip = Process.Start(startInfo))
      {
        Thread.Sleep(1000);
        sevenZip.WaitForExit();
        switch (sevenZip.ExitCode)
        {
          case 0: return; // Без ошибок и предупреждений
          case 1: return; // Есть некритичные предупреждения
          case 2: throw new Exception("Фатальная ошибка");
          case 7: throw new Exception("Ошибка в командной строке");
          case 8:
          throw new Exception("Недостаточно памяти для выполнения операции");
          case 225:
          throw new Exception("Пользователь отменил выполнение операции");
          default: throw new Exception("Архиватор 7z вернул
          недокументированный код ошибки: " + sevenZip.ExitCode.ToString());
        }
      }
    }
  }
  catch (Exception e)
  {
    throw new Exception("SevenZip.AddToArchive: " + e.Message);
  }
 }
                        
// Пример вызова функции AddToArchive
AddToArchive(@"C:\Program Files\7-Zip\7z.exe", @"C:\archive\*.*",
@"C:\archive.7z");
// После вызова AddToArchive в архиве C:\archive.7z будут лежать файлы
//из каталога C:\archive
                        

C# 7-zip извлечение из архива

Логика работы функции по извлечению из 7-zip архива ExtractFromArchive:

  1. Проверяем наличие архиватора и файла 7-zip архива. Создаем выходную директорию, если ее еще нет;
  2. Формируем экземпляр класса ProcessStartInfo, задаем в качестве аргументов имя архива и выходной каталог;
  3. Запускаем процесс 7-zip с нашими аргументами;
  4. По завершению анализируем код завершения ExitCode;
  5. Если нет критических ошибок, то заканчиваем работу;
  6. Иначе через одну секунду пробуем еще раз выполнить извлечение из архива;
  7. При повторной неудаче генерируем исключение в зависимости от кода завершения ExitCode.

                        
using System.Diagnostics;
                        
/// <summary>
 /// Распаковывает архив archiveName в каталог outputFolder
 /// </summary>
 /// <param name="archiver">файл архиватора вместе с полным путем</param>
 /// <param name="archiveName">Имя архива с полным путем</param>
 /// <param name="outputFolder">Каталог для распаковки</param>
 public static void ExtractFromArchive(string archiver, string archiveName,
string outputFolder)
 {
  try
  {
    // Предварительные проверки
    if (!File.Exists(archiver)) 
      throw new Exception("Архиватор 7z по пути \"" + archiver +
     "\" не найден");
    if (!File.Exists(archiveName)) 
      throw new Exception("Файл архива \"" + archiveName +
      "\" не найден");
    if (!Directory.Exists(outputFolder)) 
      Directory.CreateDirectory(outputFolder);
 
    // Формируем параметры вызова 7z
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.FileName = archiver;
    // Распаковать (для полных путей - x)
    startInfo.Arguments = " e"; 
    // На все отвечать yes 
    startInfo.Arguments += " -y"; 
    // Файл, который нужно распаковать 
    startInfo.Arguments += " " + "\"" + archiveName + "\""; 
    // Папка распаковки
    startInfo.Arguments += " -o" + "\"" + outputFolder + "\""; 
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    int sevenZipExitCode = 0;
    using (Process sevenZip = Process.Start(startInfo))
    {
      sevenZip.WaitForExit();
      sevenZipExitCode = sevenZip.ExitCode;
    }
    // Если с первого раза не получилось, 
    //пробуем еще раз через 1 секунду
    if (sevenZipExitCode != 0 && sevenZipExitCode != 1)
    {
      using (Process sevenZip = Process.Start(startInfo))
      {
        Thread.Sleep(1000);
        sevenZip.WaitForExit();
        switch (sevenZip.ExitCode)
        {
          case 0: return; // Без ошибок и предупреждений
          case 1: return; // Есть некритичные предупреждения
          case 2: throw new Exception("Фатальная ошибка");
          case 7: throw new Exception("Ошибка в командной строке");
          case 8:
          throw new Exception("Недостаточно памяти для выполнения операции");
          case 225:
          throw new Exception("Пользователь отменил выполнение операции");
          default: throw new Exception("Архиватор 7z вернул 
          недокументированный код ошибки: " + sevenZip.ExitCode.ToString());
        }
      }
    }
  }
  catch (Exception e)
  {
     throw new Exception("SevenZip.ExtractFromArchive: " + e.Message);
  }
 }
                        
// Пример вызова функции ExtractFromArchive
ExtractFromArchive(@"C:\Program Files\7-Zip\7z.exe", @"C:\archive.7z",
@"C:\archive");
// После вызова ExtractFromArchive в каталоге C:\archive будут лежать файлы
// из архива C:\archive.7z
                        

Вам также может быть интересно:

Каждый файл в отдельный архив 7-zip WinRAR

Маска файла с помощью регулярных выражений

назад к списку статей

Поделитесь этой страницей со своими друзьями:

Нравится


I'mon Google+ .