using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml; using System.Xml.Linq; namespace LevelUpdate { public partial class UpdateForm : Form { public UpdateForm() { InitializeComponent(); } private void UpdateForm_Load(object sender, EventArgs e) { if (!Program.NotRelationEXE) { this.button1.Text = "重启更新"; } var thraed = new Thread(new ThreadStart(delegate { try { CheckUpdate(); } catch (Exception ex) { ChangeStatus("更新失败:" + ex.Message); } })); thraed.IsBackground = true; thraed.Start(); } private void ChangeStatus(string text,params object[] objs) { if (!this.IsDisposed && !this.IsClose) { var temp = string.Format(text, objs); this.label1.Invoke(new Action(delegate { this.label1.Text = temp; })); } } string Path = System.IO.Directory.GetCurrentDirectory(); string XMLPath = string.Empty; XmlDocument XmlDoc = new XmlDocument(); #region XmlDocument读取 List need_update = new List(); InstallFileForm lodingUpdate = null; public void CheckUpdate() { XMLPath = Path + "\\LevelUpdate.xml"; if (!File.Exists(XMLPath)) throw new Exception("找不到LevelUpdate.xml必备文件!"); //使用的时候,首先声明一个XmlDocument对象,然后调用Load方法,从指定的路径加载XML文件. XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true;//忽略文档里面的注释 using (XmlReader reader = XmlReader.Create(XMLPath, settings)) { XmlDoc.Load(reader); XmlNode xn = XmlDoc.SelectSingleNode("Files"); // 得到根节点的所有子节点 XmlNodeList xnl = xn.ChildNodes; StringBuilder sb = new StringBuilder(); foreach (XmlNode node in xnl) { try { var Name = node.Attributes["Name"].Value; var Url = node.Attributes["Url"].Value; var CurVersion = Version.Parse(node.Attributes["Version"].Value); ChangeStatus("正在检测{0}文件包...",Name); XmlDocument temp_xml = new XmlDocument(); temp_xml.Load(Url); var temp_node = temp_xml.SelectSingleNode("History"); var temp_datas = temp_node.SelectNodes("Data"); //更新内容 List temp_update = new List(); foreach (XmlNode item in temp_datas) { var ver = Version.Parse(item.Attributes["Ver"].Value); if (ver > CurVersion) temp_update.Add(item); } if (temp_update.Count > 0) { sb.AppendLine(Name + "文件包更新内容如下:"); sb.AppendLine("-------------------------------"); foreach (var item in temp_update) { sb.AppendLine(item.Attributes["Ver"].Value); sb.AppendLine(item.Attributes["Msg"].Value.Replace("[br]", "\r\n")); sb.AppendLine(); } var new_data = temp_update[0]; this.richTextBox1.Invoke(new Action(delegate { this.richTextBox1.Text = sb.ToString(); })); var t = temp_update[0]; XmlAttribute attr = t.OwnerDocument.CreateAttribute("Name"); attr.Value = Name; t.Attributes.Append(attr); need_update.Add(temp_update[0]); sb.AppendLine(""); } else ChangeStatus("正在检测{0}文件包无新版本!", Name); } catch (Exception ex) { ChangeStatus("更新错误:{0}", ex.Message); } } } if (need_update.Count > 0) { ChangeStatus("发现有{0}个新文件包!", need_update.Count); this.button1.Invoke(new Action(delegate { this.button1.Enabled = true; //if(Program.NotRelationEXE) button1_Click(null,null); })); } else { ChangeStatus("没有发现新版本文件包!"); Thread.Sleep(1000); if (!this.IsDisposed && !IsClose) { this.Invoke(new Action(delegate { this.Close(); })); } } } #endregion XmlDocument读取 /// /// 退出 /// private static void Exit(bool start = false) { try { if (start) { //程序位置 string strAppFileName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; System.Diagnostics.Process myNewProcess = new System.Diagnostics.Process(); //要启动的应用程序 myNewProcess.StartInfo.FileName = strAppFileName; // 设置要启动的进程的初始目录 myNewProcess.StartInfo.WorkingDirectory = Application.ExecutablePath; //启动程序 myNewProcess.Start(); } //结束该程序 // Application.Exit(); //结束该所有线程 //Environment.Exit(0); System.Diagnostics.Process.GetCurrentProcess().Kill(); } catch (Exception) { } } public static string MapFile(string file, string path = "") { return System.IO.Path.Combine(MapPath(path, true), file); } public static string MapPath(string path = "", bool CreateDirectory = true) { if (string.IsNullOrWhiteSpace(path)) { return System.Windows.Forms.Application.StartupPath.ToString() + "\\"; } path = System.IO.Path.Combine(System.Windows.Forms.Application.StartupPath.ToString() + "\\", path); if (!(!CreateDirectory || Directory.Exists(path))) { Directory.CreateDirectory(path); } return path; } class Cmd { private static string CmdPath = @"C:\Windows\System32\cmd.exe"; /// /// 执行cmd命令 返回cmd窗口显示的信息 /// 多命令请使用批处理命令连接符: /// /// /// 执行的命令 public static string RunCmd(string cmd) { cmd = cmd.Trim().TrimEnd('&') + "&exit";//说明:不管命令是否成功均执行exit命令,否则当调用ReadToEnd()方法时,会处于假死状态 using (Process p = new Process()) { p.StartInfo.FileName = CmdPath; p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动 p.StartInfo.RedirectStandardInput = true; //接受来自调用程序的输入信息 p.StartInfo.RedirectStandardOutput = true; //由调用程序获取输出信息 p.StartInfo.RedirectStandardError = true; //重定向标准错误输出 p.StartInfo.CreateNoWindow = true; //不显示程序窗口 p.Start();//启动程序 //向cmd窗口写入命令 p.StandardInput.WriteLine(cmd); p.StandardInput.AutoFlush = true; //获取cmd窗口的输出信息 string output = p.StandardOutput.ReadToEnd(); p.WaitForExit();//等待程序执行完退出进程 p.Close(); return output; } } } private void button1_Click(object sender, EventArgs e) { if (!Program.NotRelationEXE) { var name = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName; var update = MapFile("LevelUpdate.exe"); Program.StartProcess(update, name); //this.Visible = false; Thread.Sleep(500); Exit(); return; } try { this.button1.Text = "更新中.."; this.button1.Enabled = false; var thread = new Thread(new ThreadStart(delegate { int number = 1; try { foreach (var item in need_update) { var filename = MapFile(item.Attributes["Ver"].Value + "_" + DateTime.Now.Ticks + ".zip", "Cache\\Update"); //GetPath("Cache")+ "\\Update\\"+Guid.NewGuid().ToString() + "_"+ item.Attributes["Ver"].Value + ".zip"; ChangeStatus("开始更新{0}文件包,共{1}/{2}个文件包..", item.Attributes["Name"].Value, number, need_update.Count); foreach (XmlNode _temp in XmlDoc.SelectSingleNode("Files").ChildNodes) { if (item.Attributes["Name"].Value == _temp.Attributes["Name"].Value) { _temp.Attributes["Version"].Value = item.Attributes["Ver"].Value; break; } } DownloadFile(item.Attributes["Url"].Value, filename, this.progressBar1); ChangeStatus("正在安装{0}文件包..", item.Attributes["Name"].Value); ZipArchive.UnZip(filename, Path); XmlDoc.Save(XMLPath); number++; } ChangeStatus("更新完成!"); var file_name = MapFile(Program.ExeName); Program.StartProcess(file_name); if (!IsClose && !this.IsDisposed) { this.Invoke(new Action(delegate () { this.Close(); })); } } catch (Exception ex) { ChangeStatus("更新失败:" + ex.Message); if (!IsClose) MessageBox.Show(ex.Message, "更新失败", MessageBoxButtons.OK, MessageBoxIcon.Error); } })); thread.IsBackground = true; thread.Start(); } catch (Exception ex) { ChangeStatus("更新失败:"+ex.Message); if(!IsClose) MessageBox.Show(ex.Message,"更新失败",MessageBoxButtons.OK,MessageBoxIcon.Error); } } private static Stream st = null; private static Stream so = null; private void DownloadFile(string URL, string filename, ProgressBar prog) { float percent = 0; try { if (File.Exists(filename)) File.Delete(filename); System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL); System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse(); long totalBytes = myrp.ContentLength; prog.Invoke(new Action(delegate { prog.Maximum = (int)totalBytes; })); st = myrp.GetResponseStream(); so = new System.IO.FileStream(filename, System.IO.FileMode.Create); try { long totalDownloadedByte = 0; byte[] by = new byte[1024]; int osize = st.Read(by, 0, (int)by.Length); while (osize > 0) { totalDownloadedByte = osize + totalDownloadedByte; Application.DoEvents(); so.Write(by, 0, osize); if (IsClose) return; prog.Invoke(new Action(delegate { prog.Value = (int)totalDownloadedByte; })); osize = st.Read(by, 0, (int)by.Length); percent = (float)totalDownloadedByte / (float)totalBytes * 100; Application.DoEvents(); //必须加注这句代码,否则label1将因为循环执行太快而来不及显示信息 } } catch (Exception ex) { if (so != null) { so.Close(); so.Dispose(); so = null; } if (st != null) { st.Close(); st.Dispose(); st = null; } throw ex; } finally { if (so != null) { so.Close(); so.Dispose(); so = null; } if (st != null) { st.Close(); st.Dispose(); st = null; } } } catch (Exception ex) { throw ex; } } private bool IsClose = false; private void UpdateForm_FormClosing(object sender, FormClosingEventArgs e) { IsClose = true; } } }