using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace NativeZipUtility
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
this.Text = "原生ZIP压缩解压工具";
this.Icon = SystemIcons.Application;
}
private void InitializeComponent()
{
// 主窗体设置
this.ClientSize = new System.Drawing.Size(500, 350);
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
// 压缩功能控件
var lblSourceFile = new Label { Text = "源文件:", Location = new System.Drawing.Point(20, 20), AutoSize = true };
var txtSourceFile = new TextBox { Location = new System.Drawing.Point(120, 20), Size = new System.Drawing.Size(250, 20) };
var btnBrowseSource = new Button { Text = "浏览...", Location = new System.Drawing.Point(380, 18), Size = new System.Drawing.Size(75, 23) };
btnBrowseSource.Click += (s, e) =>
{
using (var ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
txtSourceFile.Text = ofd.FileName;
}
};
var lblZipFile = new Label { Text = "ZIP文件:", Location = new System.Drawing.Point(20, 60), AutoSize = true };
var txtZipFile = new TextBox { Location = new System.Drawing.Point(120, 60), Size = new System.Drawing.Size(250, 20) };
var btnBrowseZip = new Button { Text = "浏览...", Location = new System.Drawing.Point(380, 58), Size = new System.Drawing.Size(75, 23) };
btnBrowseZip.Click += (s, e) =>
{
using (var sfd = new SaveFileDialog())
{
sfd.Filter = "ZIP文件|*.zip";
if (sfd.ShowDialog() == DialogResult.OK)
txtZipFile.Text = sfd.FileName;
}
};
var btnCompress = new Button { Text = "压缩文件", Location = new System.Drawing.Point(200, 100), Size = new System.Drawing.Size(100, 30) };
btnCompress.Click += (s, e) =>
{
try
{
if (string.IsNullOrEmpty(txtSourceFile.Text) throw new Exception("请选择源文件");
if (string.IsNullOrEmpty(txtZipFile.Text)) throw new Exception("请指定ZIP文件路径");
NativeZipHelper.CompressFile(txtSourceFile.Text, txtZipFile.Text);
MessageBox.Show("文件压缩成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"压缩失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
// 解压功能控件
var lblZipToExtract = new Label { Text = "ZIP文件:", Location = new System.Drawing.Point(20, 160), AutoSize = true };
var txtZipToExtract = new TextBox { Location = new System.Drawing.Point(120, 160), Size = new System.Drawing.Size(250, 20) };
var btnBrowseZipToExtract = new Button { Text = "浏览...", Location = new System.Drawing.Point(380, 158), Size = new System.Drawing.Size(75, 23) };
btnBrowseZipToExtract.Click += (s, e) =>
{
using (var ofd = new OpenFileDialog())
{
ofd.Filter = "ZIP文件|*.zip";
if (ofd.ShowDialog() == DialogResult.OK)
txtZipToExtract.Text = ofd.FileName;
}
};
var lblExtractPath = new Label { Text = "解压目录:", Location = new System.Drawing.Point(20, 200), AutoSize = true };
var txtExtractPath = new TextBox { Location = new System.Drawing.Point(120, 200), Size = new System.Drawing.Size(250, 20) };
var btnBrowseExtractPath = new Button { Text = "浏览...", Location = new System.Drawing.Point(380, 198), Size = new System.Drawing.Size(75, 23) };
btnBrowseExtractPath.Click += (s, e) =>
{
using (var fbd = new FolderBrowserDialog())
{
if (fbd.ShowDialog() == DialogResult.OK)
txtExtractPath.Text = fbd.SelectedPath;
}
};
var btnExtract = new Button { Text = "解压文件", Location = new System.Drawing.Point(200, 240), Size = new System.Drawing.Size(100, 30) };
btnExtract.Click += (s, e) =>
{
try
{
if (string.IsNullOrEmpty(txtZipToExtract.Text)) throw new Exception("请选择ZIP文件");
if (string.IsNullOrEmpty(txtExtractPath.Text)) throw new Exception("请指定解压目录");
NativeZipHelper.ExtractFile(txtZipToExtract.Text, txtExtractPath.Text);
MessageBox.Show("文件解压成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"解压失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
// 状态标签
var lblStatus = new Label
{
Text = "使用Windows原生Shell32实现,兼容Windows Server 2008及更早版本",
Location = new System.Drawing.Point(20, 290),
AutoSize = true,
ForeColor = System.Drawing.Color.Gray
};
// 添加控件到窗体
this.Controls.AddRange(new Control[] {
lblSourceFile, txtSourceFile, btnBrowseSource,
lblZipFile, txtZipFile, btnBrowseZip,
btnCompress,
lblZipToExtract, txtZipToExtract, btnBrowseZipToExtract,
lblExtractPath, txtExtractPath, btnBrowseExtractPath,
btnExtract,
lblStatus
});
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
public static class NativeZipHelper
{
// 压缩单个文件
public static void CompressFile(string sourceFilePath, string zipFilePath)
{
if (!File.Exists(sourceFilePath))
throw new FileNotFoundException("源文件不存在", sourceFilePath);
// 确保目标目录存在
string zipDirectory = Path.GetDirectoryName(zipFilePath);
if (!string.IsNullOrEmpty(zipDirectory) && !Directory.Exists(zipDirectory))
{
Directory.CreateDirectory(zipDirectory);
}
// 如果ZIP文件已存在,先删除
if (File.Exists(zipFilePath))
{
File.Delete(zipFilePath);
}
// 创建Shell对象
Type shellType = Type.GetTypeFromProgID("Shell.Application");
if (shellType == null)
throw new COMException("无法创建Shell.Application对象");
object shell = Activator.CreateInstance(shellType);
if (shell == null)
throw new COMException("无法实例化Shell.Application");
try
{
// 创建ZIP文件
object zipFolder = shellType.InvokeMember(
"NameSpace",
System.Reflection.BindingFlags.InvokeMethod,
null,
shell,
new object[] { zipFilePath }
);
if (zipFolder == null)
throw new COMException("无法创建ZIP文件");
// 获取源文件对象
string sourceDirectory = Path.GetDirectoryName(sourceFilePath);
string fileName = Path.GetFileName(sourceFilePath);
object sourceFolder = shellType.InvokeMember(
"NameSpace",
System.Reflection.BindingFlags.InvokeMethod,
null,
shell,
new object[] { sourceDirectory }
);
if (sourceFolder == null)
throw new COMException("无法打开源文件目录");
object sourceFileItem = sourceFolder.GetType().InvokeMember(
"ParseName",
System.Reflection.BindingFlags.InvokeMethod,
null,
sourceFolder,
new object[] { fileName }
);
if (sourceFileItem == null)
throw new COMException("无法找到源文件");
// 将文件添加到ZIP (4 = 不显示进度窗口, 16 = 覆盖已存在文件)
zipFolder.GetType().InvokeMember(
"CopyHere",
System.Reflection.BindingFlags.InvokeMethod,
null,
zipFolder,
new object[] { sourceFileItem, 20 }
);
// 等待压缩完成(Shell操作是异步的)
System.Threading.Thread.Sleep(1000);
}
finally
{
if (shell != null)
Marshal.FinalReleaseComObject(shell);
}
}
// 解压ZIP文件
public static void ExtractFile(string zipFilePath, string extractPath)
{
if (!File.Exists(zipFilePath))
throw new FileNotFoundException("ZIP文件不存在", zipFilePath);
// 确保目标目录存在
if (!Directory.Exists(extractPath))
{
Directory.CreateDirectory(extractPath);
}
// 创建Shell对象
Type shellType = Type.GetTypeFromProgID("Shell.Application");
if (shellType == null)
throw new COMException("无法创建Shell.Application对象");
object shell = Activator.CreateInstance(shellType);
if (shell == null)
throw new COMException("无法实例化Shell.Application");
try
{
// 打开ZIP文件
object zipFolder = shellType.InvokeMember(
"NameSpace",
System.Reflection.BindingFlags.InvokeMethod,
null,
shell,
new object[] { zipFilePath }
);
if (zipFolder == null)
throw new COMException("无法打开ZIP文件");
// 打开目标目录
object destFolder = shellType.InvokeMember(
"NameSpace",
System.Reflection.BindingFlags.InvokeMethod,
null,
shell,
new object[] { extractPath }
);
if (destFolder == null)
throw new COMException("无法打开目标目录");
// 获取ZIP文件内容
object items = zipFolder.GetType().InvokeMember(
"Items",
System.Reflection.BindingFlags.GetProperty,
null,
zipFolder,
null
);
if (items == null)
throw new COMException("无法获取ZIP内容");
// 执行解压操作 (20 = 4+16: 不显示UI + 覆盖已存在文件)
destFolder.GetType().InvokeMember(
"CopyHere",
System.Reflection.BindingFlags.InvokeMethod,
null,
destFolder,
new object[] { items, 20 }
);
// 等待解压完成(Shell操作是异步的)
System.Threading.Thread.Sleep(1000);
}
finally
{
if (shell != null)
Marshal.FinalReleaseComObject(shell);
}
}
}
}