tijian_jichuang/Code/SmartUpdater/UpdateUI1.cs

799 lines
25 KiB
C#
Raw Normal View History

2025-02-20 11:54:48 +08:00
using EAS.Distributed;
using EAS.Security;
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.Threading;
using System.Windows.Forms;
namespace EAS.Distributed
{
public partial class UpdateUI1 : Form
{
Thread updateThread = null;
Thread killThread = null;
DateTime lastTime = DateTime.MinValue;
DateTime sTime = DateTime.MinValue;
SmartConfig sc1 = null; //原有配置
SmartConfig sc2 = null; //新配置
IList<SmartFile> updateList = new List<SmartFile>();
IList<SmartFile> deleteList = new List<SmartFile>();
bool bComplete = false;
bool m_Kill = true;
public UpdateUI1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (XUpdate.Instance.Title.Length > 0)
this.Text = XUpdate.Instance.Title;
this.progressBar.Maximum = 0;
this.progressBar.Minimum = 0;
this.statusErrors.Text = "0个错误";
this.statusTasks.Text = "0个任务";
//1.开启升级线程。
this.updateThread = new Thread(new ThreadStart(this.AutoUpdate));
this.updateThread.Start();
#if DEBUG
using (TextLogger loggger = new TextLogger())
{
loggger.Debug(XUpdate.Instance.GetBaseDirectory());
}
#endif
//2.启动一线程,杀掉相关的应用进程。
this.killThread = new Thread(new ThreadStart(() =>
{
while (m_Kill)
{
string baseDirectory = XUpdate.Instance.GetBaseDirectory();
Process[] process = System.Diagnostics.Process.GetProcesses();
foreach (var item in process)
{
//A.本进程,跳过。
if (item.Id == Process.GetCurrentProcess().Id) //自已
{
continue;
}
bool exists = false;
#region //A2.进程名如果同引导程序,关闭之。
string pName = item.ProcessName;
if (pName.EndsWith("*32"))
{
pName = pName.Substring(0, pName.Length - 3).Trim();
}
#if DEBUG
using (TextLogger loggger = new TextLogger { Path = Path.Combine(baseDirectory, "logs"), FileName = "kill.log" })
{
loggger.Info(pName);
}
#endif
exists = string.Compare(Path.GetFileNameWithoutExtension(XUpdate.Instance.Application), item.ProcessName, true) == 0;
if (!exists)
{
exists = string.Compare(Path.GetFileName(XUpdate.Instance.Application), item.ProcessName, true) == 0;
}
#endregion
if (!exists)
{
#region dll
//B.求模块清单进程是否64位。
ProcessModuleCollection ProcessModule = null;
try
{
ProcessModule = item.Modules;
}
catch { }
if (ProcessModule != null)
{
List<ProcessModule> vList = new List<System.Diagnostics.ProcessModule>();
foreach (ProcessModule pModule in ProcessModule)
{
vList.Add(pModule);
}
try
{
vList.Add(item.MainModule);
}
catch { }
#region 32Kill
//2.判断需要Kill?
//凡加载了工作目录之中的文件的进程就强制中止。
foreach (ProcessModule pModule in vList) //循环扫描模块。
{
#region
string modueFile = string.Empty;
try
{
modueFile = pModule.FileName;
}
catch { }
#if DEBUG
//using (TextLogger loggger = new TextLogger { Path = Path.Combine(baseDirectory, "logs"), FileName = "kill.log" })
//{
// loggger.Info(modueFile);
//}
#endif
if (string.Compare(Path.GetDirectoryName(modueFile), baseDirectory, true) == 0)
{
exists = true;
break;
}
#endregion
}
#endregion
}
#endregion
}
if (exists) //执行Kill。
{
#region Kill
try
{
item.Kill();
}
catch (System.Exception exc)
{
#if DEBUG
using (TextLogger loggger = new TextLogger { Path = Path.Combine(baseDirectory, "logs"), FileName = "kill.log" })
{
loggger.Error(exc);
}
#endif
}
#endregion
}
}
//暂停100毫秒继续。
System.Threading.Thread.Sleep(50);
}
}));
killThread.Start();
}
bool CloseComplete
{
get
{
return this.checkCloseComplete.Checked;
}
set
{
this.checkCloseComplete.Checked = value;
}
}
#region UI通知
int progressMax = 0;
int progressPos = 0;
string _message = string.Empty;
bool _error = false;
void UpdateMessage(string message, bool error)
{
_message = message;
_error = error;
ChangeMessage();
}
void ChangeMessage()
{
try
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.ChangeMessage));
return;
}
this.statusMessage.Text = _message.Trim() + "...";
this.labelMessage.Text = _message.Trim() + "...";
ListViewItem item = null;
if (!_error)
{
item = this.listTasks.Items.Add(_message, 1);
this.statusTasks.Text = this.listTasks.Items.Count.ToString() + "个任务";
this.listTasks.Update();
}
else
{
string msg = _message.Replace("\n", "");
item = this.listErrors.Items.Add(_message, 0);
this.statusErrors.Text = this.listErrors.Items.Count.ToString() + "个错误";
this.listErrors.Update();
}
}
catch { }
}
void UpdateProgress(int pos, int total)
{
progressMax = total;
progressPos = pos;
ChangeProgress();
}
void ChangeProgress()
{
try
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.ChangeProgress));
return;
}
this.progressBar.Maximum = progressMax;
this.progressBar.Value = progressPos;
}
catch { }
}
void ShowClose()
{
try
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.ShowClose));
return;
}
this.btnCancel.Visible = false;
this.btnClose.Visible = true;
}
catch { }
}
#endregion
/// <summary>
/// 检测是否需要更新。
/// </summary>
/// <returns></returns>
bool CheckUpdate()
{
updateList.Clear();
//判断
if (!XUpdate.Instance.AllowUpdate)
{
this.UpdateMessage("系统不需要升级", true);
this.UpdateProgress(500, 500);
this.bComplete = false;
return false;
}
if (XUpdate.Instance.Service == null)
{
try
{
XUpdate.GetService();
}
catch (System.Exception exc)
{
this.UpdateMessage("初始化服务参数出错,错误:" + exc.Message, false);
this.UpdateProgress(500, 500);
this.bComplete = false;
return false;
}
}
if (XUpdate.Instance.Service == null)
{
this.bComplete = false;
return false;
}
//读本地文件。
string file = Path.Combine(XUpdate.Instance.GetBaseDirectory(), SmartConfig.DefaultConfgiFile);
if (File.Exists(file))
{
try
{
sc1 = XUpdate.LoadSmartAssemblyList();
lastTime = sc1.Time;
}
catch
{
this.UpdateProgress(500, 500);
this.bComplete = false;
return false;
}
}
//生成升级清单。
this.GenUpdateList();
bool update = this.updateList.Count > 0;
if (!update)
{
this.UpdateMessage("系统已是最新版本", false);
string buffer = XUpdate.Instance.Service.GetSmartUpdateConfig();
sc2 = SmartConfig.LoadXML(buffer);
string configFile = Path.Combine(XUpdate.Instance.GetBaseDirectory(), SmartConfig.DefaultConfgiFile);
SmartConfig.Save(this.sc2, configFile);
this.UpdateProgress(500, 500);
this.bComplete = true;
}
return update;
}
/// <summary>
/// 生成更新清单。
/// </summary>
/// <returns></returns>
void GenUpdateList()
{
updateList = new List<SmartFile>();
//A1.原有配置。
if (sc1 == null)
{
sc1 = new SmartConfig();
}
//B.下载新配置
try
{
string buffer = XUpdate.Instance.Service.GetSmartUpdateConfig();
sc2 = SmartConfig.LoadXML(buffer);
}
catch (System.Exception exc)
{
this.UpdateMessage("下载程序集清单出错,错误:" + exc.Message, true);
this.UpdateProgress(500, 500);
return;
}
if (sc2 == null)
sc2 = new SmartConfig();
//X1.在远程之中循环,排除在本地清单之中并且时间没有变更的记录。
foreach (SmartFile item in sc2.Files)
{
var sFile = sc1.Files
.Where(p => string.Compare(p.FileName, item.FileName, true) == 0)
.FirstOrDefault();
if (sFile == null)
{
updateList.Add(item);
}
else if (sFile.Time != item.Time)
{
updateList.Add(item);
}
}
//X2.在远程清单之中但是本地没有文件。
string baseDirectory = XUpdate.Instance.GetBaseDirectory();
foreach (SmartFile item in sc2.Files)
{
string descFile = Path.Combine(baseDirectory, item.FileName);
if (!File.Exists(descFile))
{
int count = updateList
.Where(p => string.Compare(p.FileName, item.FileName, true) == 0)
.Count();
if (count == 0)
{
updateList.Add(item);
}
}
}
}
/// <summary>
/// 生成删除清单。
/// </summary>
/// <remarks>
/// 删除不必要的文件,即如果服务端删除了某些文件客户段如何处理。
/// </remarks>
/// <returns></returns>
void GenDeleteList()
{
//添加服务程序集到一个Key-Value之中
Dictionary<string, SmartFile> smartFiles = new Dictionary<string, SmartFile>();
foreach (SmartFile item in sc2.Files)
{
if (!smartFiles.ContainsKey(item.FileName))
{
smartFiles.Add(item.FileName, item);
}
}
//求在本地清单之中,不在服务器清单之中的。
foreach (SmartFile item in sc1.Files)
{
if (!smartFiles.ContainsKey(item.FileName))
{
deleteList.Add(item);
}
}
}
/// <summary>
/// 下载文件。
/// </summary>
/// <param name="sf"></param>
void DownFile(SmartFile sf)
{
string downDirectory = XUpdate.Instance.GetDownDirectory();
if (!Directory.Exists(downDirectory))
Directory.CreateDirectory(downDirectory);
try
{
XUpdate.GetService();
byte[] buffer = XUpdate.Instance.Service.DownloadSmartFile(sf.FileName);
buffer = Compressor.Decompress(buffer);
string fileName = Path.Combine(downDirectory, sf.FileName);
//子文件夹的创建。
string xPath = Path.GetDirectoryName(fileName);
if (!Directory.Exists(xPath))
{
try
{
Directory.CreateDirectory(xPath);
}
catch { }
}
//写文件。
File.WriteAllBytes(fileName, buffer);
}
catch (System.Exception exc)
{
this.UpdateMessage("下载组件" + Path.GetFileName(sf.FileName) + "出错,错误:" + exc.Message, true);
return;
}
}
/// <summary>
/// 移动文件。
/// </summary>
void MoveFiles()
{
string downDirectory = XUpdate.Instance.GetDownDirectory();
string baseDirectory = XUpdate.Instance.GetBaseDirectory();
if (!Directory.Exists(downDirectory))
return;
//1.移动文件
foreach (SmartFile sf in this.updateList)
{
string sourceFile = Path.Combine(downDirectory, sf.FileName);
string descFile = Path.Combine(baseDirectory, sf.FileName);
//子文件夹的创建。
string xPath = Path.GetDirectoryName(descFile);
if (!Directory.Exists(xPath))
{
try
{
Directory.CreateDirectory(xPath);
}
catch { }
}
if (File.Exists(sourceFile) && File.Exists(descFile))
{
try
{
File.Delete(descFile);
}
catch { }
}
if (File.Exists(sourceFile))
{
string dt = Path.GetDirectoryName(descFile);
if (!Directory.Exists(dt))
try
{
Directory.CreateDirectory(dt);
}
catch { }
try
{
File.Move(sourceFile, descFile);
}
catch { }
}
}
//2.删除目录
string[] files = Directory.GetFiles(downDirectory, "*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
try
{
File.Delete(file);
}
catch { }
}
files = Directory.GetDirectories(downDirectory, "*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
try
{
Directory.Delete(file);
}
catch { }
}
if (Directory.Exists(downDirectory))
try
{
Directory.Delete(downDirectory);
}
catch { }
//3.删除文件
foreach (SmartFile sf in this.deleteList)
{
string descFile = Path.Combine(baseDirectory, sf.FileName);
if (File.Exists(descFile) &&
!sf.FileName.EndsWith("EAS.SmartUpdater.exe", StringComparison.CurrentCultureIgnoreCase) &&
!sf.FileName.EndsWith("update.ini", StringComparison.CurrentCultureIgnoreCase))
{
try
{
File.Delete(descFile);
}
catch { }
}
}
//写配置
string configFile = Path.Combine(XUpdate.Instance.GetBaseDirectory(), SmartConfig.DefaultConfgiFile);
SmartConfig.Save(this.sc2, configFile);
}
void OnDataTransmit(System.EventArgs e)
{
UpdateMessage("判断系统是否需要更新", false);
this.UpdateProgress(1, 500);
bool update = this.CheckUpdate();
if (!update)
{
return;
}
//检查需要更新的程序集
this.UpdateMessage("下载升级清单", false);
this.UpdateProgress(2, 500);
this.GenUpdateList();
this.GenDeleteList();
if (this.updateList.Count == 0 && this.deleteList.Count == 0)
{
this.UpdateMessage("没有需要更新的组件", false);
this.UpdateProgress(500, 500);
//写配置
string configFile = Path.Combine(XUpdate.Instance.GetBaseDirectory(), SmartConfig.DefaultConfgiFile);
SmartConfig.Save(this.sc2, configFile);
this.bComplete = true;
//终止Kill纯程
this.m_Kill = false;
System.Threading.Thread.Sleep(100);
//关闭
btnClose_Click(this.btnClose, e);
return;
}
#region //删除待升级文件。
foreach (var sf in this.updateList)
{
string vDirectory = XUpdate.Instance.GetBaseDirectory();
string vFile = Path.Combine(vDirectory, sf.FileName);
if (File.Exists(vFile) &&
!sf.FileName.EndsWith("EAS.SmartUpdater.exe", StringComparison.CurrentCultureIgnoreCase) &&
!sf.FileName.EndsWith("update.ini", StringComparison.CurrentCultureIgnoreCase))
{
try
{
File.Delete(vFile);
}
catch { }
}
}
#endregion
//检查需要更新的程序集
this.UpdateMessage("准备下载文件", false);
this.UpdateProgress(3, 500);
int xProgress = 5 * this.updateList.Count + 10;
int index = 1;
foreach (SmartFile sf in this.updateList)
{
this.UpdateMessage("准备下载" + Path.GetFileName(sf.FileName) + "", false);
this.DownFile(sf);
this.UpdateMessage(Path.GetFileName(sf.FileName) + "完成下载", false);
this.UpdateProgress(5 * index, xProgress);
index++;
}
//
this.UpdateMessage("准备更新系统", false);
this.MoveFiles();
this.UpdateProgress(xProgress - 5, xProgress);
if (sc2.StartEx.Length > 0)
{
string cmd = XUpdate.Instance.GetBaseDirectory() + " " + sc2.StartEx;
System.Diagnostics.Process.Start(cmd);
}
//终止Kill纯程
this.m_Kill = false;
System.Threading.Thread.Sleep(100);
this.UpdateMessage("升级完成", false);
this.UpdateProgress(xProgress, xProgress);
this.bComplete = true;
}
void AutoUpdate()
{
bComplete = false;
try
{
this.OnDataTransmit(new System.EventArgs());
if (this.checkCloseComplete.Checked)
{
//this.Close();
System.Windows.Forms.Application.Exit();
}
}
catch (System.Threading.ThreadAbortException abortExc)
{
this.UpdateMessage(abortExc.Message, true);
}
catch (System.Exception exc)
{
this.UpdateMessage(exc.Message, true);
}
finally
{
this.ShowClose();
}
}
private void btnDetails_Click(object sender, System.EventArgs e)
{
if (this.buttonDetails.Text == "<< 详细")
{
this.buttonDetails.Text = "详细 >>";
this.tabControl.Visible = false;
this.Height = this.Height - this.tabControl.Height;
}
else
{
this.buttonDetails.Text = "<< 详细";
tabControl.Visible = true;
this.Height = this.Height + this.tabControl.Height;
}
}
private void btnCancel_Click(object sender, System.EventArgs e)
{
this.btnCancel.Enabled = false;
Cursor = Cursors.WaitCursor;
try
{
this.updateThread.Abort();
}
catch { }
this.m_Kill = false;
System.Threading.Thread.Sleep(100);
Cursor = Cursors.Default;
this.UpdateMessage("操作被取消", true);
this.btnClose.Visible = true;
tabControl.SelectedIndex = 1;
}
private void btnClose_Click(object sender, System.EventArgs e)
{
this.m_Kill = false;
System.Threading.Thread.Sleep(100);
if (this.bComplete)
{
if (this.updateList.Count >= 1)
{
MessageBox.Show(this, "系统升级完成,共升级了" + this.updateList.Count + "个应用程序模块,应用程序将重新启动!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Thread m_StartThread = new Thread(new ThreadStart(() =>
{
try
{
System.Diagnostics.Process.Start(XUpdate.Instance.Application);
}
catch { }
}));
m_StartThread.Start();
}
//this.Close();
System.Windows.Forms.Application.Exit();
}
private void listErrors_SelectedIndexChanged(object sender, System.EventArgs e)
{
if (this.listErrors.SelectedItems.Count > 0)
{
this.textError.Text = this.listErrors.SelectedItems[0].Text;
}
else
{
this.textError.Text = string.Empty;
}
}
private void UpdateUI_Load(object sender, EventArgs e)
{
}
}
}