编辑:如果您使用的是 .Net 4.5 或更高版本,这是built-in to the framework
对于早期版本或更多控制,您可以使用here on CodeProject by Gerald Gibson Jr 概述的 Windows 的 shell 函数。
我已将下面的文章文字照原样复制(原始许可:public domain)
使用 Windows Shell API 和 C 压缩 Zip 文件
简介
这是我写的关于解压缩 Zip 文件的文章的后续文章。使用此代码,您可以使用 C# 中的 Windows Shell API 来压缩 Zip 文件,并且无需显示上面显示的“复制进度”窗口。通常,当您使用 Shell API 压缩 Zip 文件时,即使您设置选项告诉 Windows 不显示它,它也会显示“复制进度”窗口。为了解决这个问题,您将 Shell API 代码移动到一个单独的可执行文件,然后使用 .NET Process 类启动该可执行文件,确保将进程窗口样式设置为“隐藏”。
背景
曾经需要压缩 Zip 文件并且需要比许多免费压缩库提供的更好的 Zip? IE。您需要压缩文件夹和子文件夹以及文件。 Windows Zipping 可以压缩的不仅仅是单个文件。您所需要的只是一种以编程方式让 Windows 静默压缩这些 Zip 文件的方法。当然,您可以在其中一个商业 Zip 组件上花费 300 美元,但如果您只需要压缩文件夹层次结构,就很难免费获得。
使用代码
以下代码显示了如何使用 Windows Shell API 来压缩 Zip 文件。首先,您创建一个空的 Zip 文件。为此,请创建一个正确构造的字节数组,然后将该数组保存为扩展名为“.zip”的文件。我怎么知道要放入数组中的字节?好吧,我只是使用 Windows 创建了一个 Zip 文件,其中包含一个压缩文件。然后我用 Windows 打开 Zip 并删除了压缩文件。这给我留下了一个空的Zip。接下来,我在十六进制编辑器 (Visual Studio) 中打开空的 Zip 文件,查看十六进制字节值并使用 Windows Calc 将它们转换为十进制,并将这些十进制值复制到我的字节数组代码中。源文件夹指向您要压缩的文件夹。目标文件夹指向您刚刚创建的空 Zip 文件。此代码将按原样压缩 Zip 文件,但它也会显示“复制进度”窗口。要使此代码正常工作,您还需要设置对 COM 库的引用。在 References 窗口中,转到 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,而不显示“复制进度”窗口。
下面的代码显示了一个按钮单击事件处理程序,其中包含用于启动控制台应用程序的代码,因此在压缩期间没有 UI:
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");
}