using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;
namespace rycUpdate
{
    public partial class frmmain : Form
    {
        #region 删除文件
        [DllImport("shell32.dll")]
        private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
        /// 
        /// 执行删除。成功返回空，否则返回错误信息。
        /// 
        /// 
        /// 
        public static int FilesDelete(string path)
        {
            SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT();
            lpFileOp.wFunc = wFunc.FO_DELETE;
            lpFileOp.pFrom = path + "\0";
            lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOCONFIRMATION | FILEOP_FLAGS.FOF_NOERRORUI | FILEOP_FLAGS.FOF_SILENT;
            lpFileOp.fFlags &= ~FILEOP_FLAGS.FOF_ALLOWUNDO;
            lpFileOp.fAnyOperationsAborted = false;

            int n = SHFileOperation(ref lpFileOp);
            if (n != 0) return 1;
            return 0;
            //string tmp = GetErrorString(n);

            //.av 文件正常删除了但也提示 402 错误，不知道为什么。屏蔽之。
            //if ((path.ToLower().EndsWith(".av") && n.ToString("X") == "402")) return string.Empty;
        }

        private struct SHFILEOPSTRUCT
        {
            public IntPtr hwnd;
            public wFunc wFunc;
            public string pFrom;
            public string pTo;
            public FILEOP_FLAGS fFlags;
            public bool fAnyOperationsAborted;
            public IntPtr hNameMappings;
            public string lpszProgressTitle;
        }

        private enum wFunc
        {
            FO_MOVE = 0x0001,
            FO_COPY = 0x0002,
            FO_DELETE = 0x0003,
            FO_RENAME = 0x0004
        }

        private enum FILEOP_FLAGS
        {
            FOF_MULTIDESTFILES = 0x0001, //pTo 指定了多个目标文件，而不是单个目录
            FOF_CONFIRMMOUSE = 0x0002,
            FOF_SILENT = 0x0044, // 不显示一个进度对话框
            FOF_RENAMEONCOLLISION = 0x0008, // 碰到有抵触的名字时，自动分配前缀
            FOF_NOCONFIRMATION = 0x10, // 不对用户显示提示
            FOF_WANTMAPPINGHANDLE = 0x0020, // 填充 hNameMappings 字段，必须使用 SHFreeNameMappings 释放
            FOF_ALLOWUNDO = 0x40, // 允许撤销
            FOF_FILESONLY = 0x0080, // 使用 *.* 时, 只对文件操作
            FOF_SIMPLEPROGRESS = 0x0100, // 简单进度条，意味者不显示文件名。
            FOF_NOCONFIRMMKDIR = 0x0200, // 建新目录时不需要用户确定
            FOF_NOERRORUI = 0x0400, // 不显示出错用户界面
            FOF_NOCOPYSECURITYATTRIBS = 0x0800, // 不复制 NT 文件的安全属性
            FOF_NORECURSION = 0x1000 // 不递归目录
        }
        #endregion
        string commandStr = "";
        public frmmain()
        {
            InitializeComponent();
        }
        public frmmain(string[] args)
        {
            commandStr = args[0];
            InitializeComponent();
        }
        private void frmmain_Load(object sender, EventArgs e)
        {
            clsPram.myHandle = System.Diagnostics.Process.GetCurrentProcess().Handle.ToInt32();
            timer1.Enabled = true;
        }
        public int RunFile(string FilePath, string PramCom)
        {
            try
            {
                System.Diagnostics.Process.Start(FilePath, PramCom);
                return 1;
            }
            catch { return 0; }
        }
        public void CopyFiles(string varFromDirectory, string varToDirectory)
        {//实现从一个目录下完整拷贝到另一个目录下。
            //Directory.CreateDirectory(varToDirectory);
            if (!Directory.Exists(varFromDirectory))
            {
                //m_eorrStr = "对不起，您要拷贝的目录不存在。 ";
                return;
            }
            string[] directories = Directory.GetDirectories(varFromDirectory);//取文件夹下所有文件夹名，放入数组；
            if (directories.Length > 0)
            {
                foreach (string d in directories)
                {
                    try
                    {
                        CopyFiles(d, varToDirectory + d.Substring(d.LastIndexOf("\\ ")));//递归拷贝文件和文件夹
                    }
                    catch { }
                }
            }
            string[] files = Directory.GetFiles(varFromDirectory);//取文件夹下所有文件名，放入数组；
            if (files.Length > 0)
            {
                foreach (string s in files)
                {
                    try
                    {
                        File.Copy(s, varToDirectory + s.Substring(s.LastIndexOf("\\ ")));
                    }
                    catch { }
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //try
            {
                timer1.Stop();
                lblShow.Text = "正在校验升级文件。。。";
                Application.DoEvents();
                clsPram.UpdateZipPath = Application.StartupPath + "\\Update\\tmp.tmp";
                clsPram.UnZipPath = Application.StartupPath + "\\Update\\tmp";
                if (commandStr == "update") //如果是第一次调用，就是解压升级
                {
                    #region 第一轮，解压升级
                    if (System.IO.File.Exists(clsPram.UpdateZipPath) == false) //如果升级文件不存在，那么就升级失败
                    {
                        MessageBox.Show("升级文件不存在，升级中断。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.Close();
                        return;
                    }
                    if (System.IO.Directory.Exists(clsPram.UnZipPath)) //如果解压文件夹已经存在，那么就先删除
                    {
                        FilesDelete(clsPram.UnZipPath);
                    }
                    lblShow.Text = "正在解包升级文件。。。";
                    Application.DoEvents();
                    try
                    {
                        UnZipClass.UnZip(clsPram.UpdateZipPath, clsPram.UnZipPath, "");//解压到指定文件夹
                    }
                    catch
                    {
                        MessageBox.Show("升级包校验出错，升级中断。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.Close();
                        return;
                    }
                    ryCommon.clsStorage tStor = new ryCommon.clsStorage();
                    tStor.LoadFromFile(Application.StartupPath + "\\tmp.updx");
                    tStor.SelectNode2("id", "KillProcList");
                    clsPram.KillMultiProcess(tStor.GetAttrValue("Value", ""));
                    lblShow.Text = "正在复制升级文件。。。";
                    Application.DoEvents();
                    Thread.Sleep(500);
                    Common.Files.FileOperator cf = new Common.Files.FileOperator();
                    cf.CopyDirectoryAndFiles(clsPram.UnZipPath, Application.StartupPath);
                    //如果升级包里面存在升级程序，则说明这是软件升级，否则表示数据库升级
                    if (System.IO.File.Exists(clsPram.UnZipPath + "\\" + clsPram.UpdateFileName))
                    {
                        try
                        {
                            FilesDelete(Application.StartupPath + "\\" + clsPram.newUpdateFileName);
                            //复制升级文件过来
                            File.Copy(clsPram.UnZipPath + "\\" + clsPram.UpdateFileName, Application.StartupPath + "\\" + clsPram.newUpdateFileName, true);
                        }
                        catch { }
                        RunFile(Application.StartupPath + "\\" + clsPram.newUpdateFileName, "replace");
                    }
                    else
                    {
                        tStor.SelectNode2("id", "MainProcName");
                        clsPram.MainName = tStor.GetAttrValue("Value", "");
                        RunFile(Application.StartupPath + "\\" + clsPram.MainName, "");
                    }
                    this.Close();

                    #endregion
                }
                else if (commandStr == "replace")//完成升级程序的替换
                {
                    #region 第二轮程序替换
                    lblShow.Text = "正在替换升级文件。。。";
                    Application.DoEvents();
                    clsPram.KillProcess(clsPram.UpdateFileName);//结束之前的升级进程
                    Thread.Sleep(700);
                    try
                    {
                        FilesDelete(Application.StartupPath + "\\" + clsPram.UpdateFileName);
                        //升级文件替换
                        File.Copy(Application.StartupPath + "\\" + clsPram.newUpdateFileName, Application.StartupPath + "\\" + clsPram.UpdateFileName,true);
                    }
                    catch { }
                    RunFile(Application.StartupPath + "\\" + clsPram.UpdateFileName, "del");
                    this.Close();
                    #endregion
                }
                else if (commandStr == "del")//做最后清理工作
                {
                    #region 第三轮清理工作
                    lblShow.Text = "正在删除升级残余文件。。。";
                    Application.DoEvents();
                    ryCommon.clsStorage tStor = new ryCommon.clsStorage();
                    tStor.LoadFromFile(Application.StartupPath + "\\tmp.updx");
                    tStor.SelectNode2("id", "MainProcName");
                    clsPram.MainName = tStor.GetAttrValue("Value", "");
                    Thread.Sleep(1000);
                    clsPram.KillProcess(clsPram.newUpdateFileName);//结束之前的升级进程
                    try
                    {
                        //删除旧的升级文件
                        FilesDelete(Application.StartupPath + "\\" + clsPram.newUpdateFileName);
                        FilesDelete(Application.StartupPath + "\\Update");
                        FilesDelete(Application.StartupPath + "\\tmp.updx");
                    }
                    catch { }
                    RunFile(Application.StartupPath + "\\" + clsPram.MainName, "");
                    this.Close();
                    #endregion
                }
                else
                {
                    this.Close();
                }
            }
            //catch { this.Close(); }
        }


    }
}
