Редактировать: если вы используете .Net 4.5 или более позднюю версию, это встроено в фреймворк
Для более ранних версий или для большего контроля вы можете использовать функции оболочки Windows, как описано здесь, в CodeProject, автор Gerald Gibson Jr .
Я скопировал текст статьи ниже как написано (оригинальная лицензия: общественное достояние )
Сжатие Zip-файлов с помощью Windows Shell API и C
Введение
Это продолжение статьи, которую я написал о распаковке Zip-файлов. С помощью этого кода вы можете использовать Windows Shell API в C # для сжатия Zip-файлов и делать это без отображения окна «Ход выполнения копирования», показанного выше. Обычно, когда вы используете Shell API для сжатия Zip-файла, он будет отображать окно «Ход выполнения копирования», даже если вы установили параметры, чтобы запретить Windows показывать его. Чтобы обойти это, вы перемещаете код API оболочки в отдельный исполняемый файл, а затем запускаете этот исполняемый файл, используя класс .NET Process, обязательно устанавливая стиль окна процесса на «Скрытый».
Фон
Всегда нужно было сжимать Zip-файлы и нужен был лучший Zip, чем то, что поставляется со многими бесплатными библиотеками сжатия? То есть вам нужно было сжать папки и подпапки, а также файлы. Windows Zipping может сжимать не только отдельные файлы. Все, что вам нужно, это способ программно заставить Windows тихо сжать эти файлы Zip. Конечно, вы могли бы потратить 300 долларов на один из коммерческих компонентов Zip, но его трудно превзойти, если все, что вам нужно, - это сжать иерархии папок.
Использование кода
В следующем коде показано, как использовать Windows Shell API для сжатия файла Zip. Сначала вы создаете пустой Zip-файл. Для этого создайте правильно сконструированный байтовый массив, а затем сохраните этот массив в виде файла с расширением .zip. Как я узнал, какие байты поместить в массив? Ну, я просто использовал Windows, чтобы создать файл Zip с одним сжатым файлом внутри. Затем я открыл Zip с Windows и удалил сжатый файл. Это оставило меня с пустым почтовым индексом. Затем я открыл пустой Zip-файл в шестнадцатеричном редакторе (Visual Studio), посмотрел значения шестнадцатеричных байтов, преобразовал их в десятичные с помощью Windows Calc и скопировал эти десятичные значения в код моего байтового массива. Исходная папка указывает на папку, которую вы хотите сжать. Папка назначения указывает на пустой Zip-файл, который вы только что создали. Этот код, как есть, сожмет Zip-файл, однако он также покажет окно копирования. Чтобы этот код работал, вам также необходимо установить ссылку на библиотеку COM. В окне «Ссылки» перейдите на вкладку «COM» и выберите библиотеку с надписью «Microsoft Shell Controls and Automation».
//Create an empty zip file
byte[] emptyzip = new byte[]{80,75,5,6,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
FileStream fs = File.Create(args[1]);
fs.Write(emptyzip, 0, emptyzip.Length);
fs.Flush();
fs.Close();
fs = null;
//Copy a folder and its contents into the newly created zip file
Shell32.ShellClass sc = new Shell32.ShellClass();
Shell32.Folder SrcFlder = sc.NameSpace(args[0]);
Shell32.Folder DestFlder = sc.NameSpace(args[1]);
Shell32.FolderItems items = SrcFlder.Items();
DestFlder.CopyHere(items, 20);
//Ziping a file using the Windows Shell API
//creates another thread where the zipping is executed.
//This means that it is possible that this console app
//would end before the zipping thread
//starts to execute which would cause the zip to never
//occur and you will end up with just
//an empty zip file. So wait a second and give
//the zipping thread time to get started
System.Threading.Thread.Sleep(1000);
Пример решения, включенного в эту статью, показывает, как поместить этот код в консольное приложение, а затем запустить это консольное приложение, чтобы сжать Zip без отображения окна «Ход выполнения копирования».
Приведенный ниже код показывает обработчик события нажатия кнопки, который содержит код, используемый для запуска консольного приложения, чтобы не было пользовательского интерфейса во время сжатия:
private void btnUnzip_Click(object sender, System.EventArgs e)
{
//Test to see if the user entered a zip file name
if(txtZipFileName.Text.Trim() == "")
{
MessageBox.Show("You must enter what" +
" you want the name of the zip file to be");
//Change the background color to cue the user to what needs fixed
txtZipFileName.BackColor = Color.Yellow;
return;
}
else
{
//Reset the background color
txtZipFileName.BackColor = Color.White;
}
//Launch the zip.exe console app to do the actual zipping
System.Diagnostics.ProcessStartInfo i =
new System.Diagnostics.ProcessStartInfo(
AppDomain.CurrentDomain.BaseDirectory + "zip.exe");
i.CreateNoWindow = true;
string args = "";
if(txtSource.Text.IndexOf(" ") != -1)
{
//we got a space in the path so wrap it in double qoutes
args += "\"" + txtSource.Text + "\"";
}
else
{
args += txtSource.Text;
}
string dest = txtDestination.Text;
if(dest.EndsWith(@"\") == false)
{
dest += @"\";
}
//Make sure the zip file name ends with a zip extension
if(txtZipFileName.Text.ToUpper().EndsWith(".ZIP") == false)
{
txtZipFileName.Text += ".zip";
}
dest += txtZipFileName.Text;
if(dest.IndexOf(" ") != -1)
{
//we got a space in the path so wrap it in double qoutes
args += " " + "\"" + dest + "\"";
}
else
{
args += " " + dest;
}
i.Arguments = args;
//Mark the process window as hidden so
//that the progress copy window doesn't show
i.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(i);
p.WaitForExit();
MessageBox.Show("Complete");
}