414 lines
16 KiB
C#
414 lines
16 KiB
C#
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<XmlNode> need_update = new List<XmlNode>();
|
||
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<XmlNode> temp_update = new List<XmlNode>();
|
||
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读取
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 退出
|
||
/// </summary>
|
||
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";
|
||
/// <summary>
|
||
/// 执行cmd命令 返回cmd窗口显示的信息
|
||
/// 多命令请使用批处理命令连接符:
|
||
/// <![CDATA[
|
||
/// &:同时执行两个命令
|
||
/// |:将上一个命令的输出,作为下一个命令的输入
|
||
/// &&:当&&前的命令成功时,才执行&&后的命令
|
||
/// ||:当||前的命令失败时,才执行||后的命令]]>
|
||
/// </summary>
|
||
/// <param name="cmd">执行的命令</param>
|
||
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;
|
||
}
|
||
}
|
||
}
|