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);
            }
        }
    }
}