old_flsystem/类库/Update/UpdateForm.cs

414 lines
16 KiB
C#
Raw Permalink Normal View History

2022-09-20 03:10:29 +00:00
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;
}
}
}