using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Version.Update.Commons; using Version.Update.Models; using Y.Utils.DataUtils.Collections; using Y.Utils.DataUtils.JsonUtils; using Y.Utils.IOUtils.FileUtils; using Y.Utils.IOUtils.PathUtils; using Y.Utils.NetUtils.FTPUtils; using Y.Utils.WindowsUtils.ProcessUtils; namespace Version.Update { public partial class Form1 : Form { string downloadPath = ""; VersionModel version; int Step = 1, Error = 1; int SmallHeight = 146; int LargeHeight = 420; public Form1() { InitializeComponent(); Height = SmallHeight; LbRetry.Visible = false; } private void Form1_Load(object sender, EventArgs e) { UpdateTask(); } #region 更新功能 /// /// 完整的更新任务 /// void UpdateTask() { LbRetry.Visible = false; Step = 1; Error = 1; string folder = Guid.NewGuid().ToString(); downloadPath = R.AppPath + @"Temp\Update\" + folder; Task.Factory.StartNew(() => { UILbStatus("[准备] 正在读取版本文件..."); if (GetVersion()) { UILbStatus("[准备] 正在读取版本文件...[完成]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); if (Step == 1) { UILbStatus("[1/5] 正在退出相关程序..."); BeginCloseProcess(); Thread.Sleep(R.cst.STEP_WAIT_TIME); UILbStatus("[1/5] 正在退出相关程序...[完成]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); } if (Step == 2) { UILbStatus("[2/5] 正在下载新版本的文件..."); DownloadFile(downloadPath); Thread.Sleep(R.cst.STEP_WAIT_TIME); UILbStatus("[2/5] 正在下载新版本的文件...[完成]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); } if (Step == 3) { UILbStatus("[3/5] 正在更新文件..."); UpdateFile(downloadPath); Thread.Sleep(R.cst.STEP_WAIT_TIME); UILbStatus("[3/5] 正在更新文件...[完成]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); } if (Step == 4) { UILbStatus("[4/5] 正在清理冗余文件..."); CleanFile(); Thread.Sleep(R.cst.STEP_WAIT_TIME); UILbStatus("[4/5] 正在清理冗余文件...[完成]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); } if (Step == 5) { UILbStatus("[5/5] 准备启动程序..."); EndRunProcess(); UILbStatus("[5/5] 准备启动程序...[完成]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); } if (Error > 0) { UILbStatus("[更新成功 即将退出]"); Thread.Sleep(R.cst.STEP_WAIT_TIME); UIClose(); } else { UILbStatus("[更新异常 请检查并解决故障后 重新更新]"); UIShowRetry(); } } else { UILbStatus("[结束] 未发现新版本..."); MessageBox.Show("您已经是最新版本了。", "完成"); UIClose(); } }); } /// /// 获取版本配置文件 /// /// bool GetVersion() { version = JsonTool.ToObjFromFile(R.VersionFile); if (version != null) { try { int num = 1; foreach (var item in version.FileList) { UIDgvFileListAdd(new object[] { num++, Path.GetFileName(item.File) }); Thread.Sleep(R.cst.WAIT_TIME); } return true; } catch (Exception e) { } } return false; } /// /// 下载程序文件 /// /// bool DownloadFile(string downloadPath) { if (DirTool.Create(downloadPath)) { FileCodeTool fcode = new FileCodeTool(); for (int i = 0; i < version.FileList.Count; i++) { string fileName = Path.GetFileName(version.FileList[i].File); string sourceFile = version.ServerPath + version.FileList[i].File; string destFile = downloadPath + version.FileList[i].File; string destPath = destFile.Substring(0, destFile.Length - fileName.Length); if (DirTool.Create(destPath)) { if (File.Exists(R.AppPath + version.FileList[i].File) && version.FileList[i].MD5 == fcode.GetMD5(R.AppPath + version.FileList[i].File)) { UIDgvFileListUpdate(i, "ColDown", R.cst.FILE_JUMP); } else { FtpTool ftp = new FtpTool(R.FtpIp, R.FtpAccount, R.FtpPassword); if (!ftp.DownloadFile(sourceFile, destPath)) if (!ftp.DownloadFile(sourceFile, destPath)) if (!ftp.DownloadFile(sourceFile, destPath)) { MessageBox.Show("更新文件无法被下载,请检查网络重试,谢谢。", "网络故障"); Step = 5; Error = -201; return false; } UIDgvFileListUpdate(i, "ColDown", R.cst.FILE_SUCC); } } else { UIDgvFileListUpdate(i, "ColDown", R.cst.FILE_FAIL); } Thread.Sleep(R.cst.WAIT_TIME); } } Step = 3; return true; } /// /// 更新程序文件 /// /// bool UpdateFile(string downloadPath) { for (int i = 0; i < version.FileList.Count; i++) { string fileName = Path.GetFileName(version.FileList[i].File); string sourceFile = downloadPath + version.FileList[i].File; string destFile = R.AppPath + version.FileList[i].File; string destPath = destFile.Substring(0, destFile.Length - fileName.Length); if (DirTool.Create(destPath)) { try { if (File.Exists(sourceFile)) { File.Copy(sourceFile, destFile, true); UIDgvFileListUpdate(i, "ColUpdate", R.cst.FILE_SUCC); } else { UIDgvFileListUpdate(i, "ColUpdate", R.cst.FILE_JUMP); } } catch (Exception e) { UIDgvFileListUpdate(i, "ColUpdate", R.cst.FILE_FAIL); } } else { UIDgvFileListUpdate(i, "ColBack", R.cst.FILE_FAIL); } Thread.Sleep(R.cst.WAIT_TIME); } Step = 4; return false; } /// /// 清理之前版本遗留文件及空文件夹 /// /// void CleanFile() { UIPbStatus(0); #region 删除下载的更新文件和版本文件 try { Directory.Delete(R.AppPath + @"Temp\Update\", true); File.Delete(R.VersionFile); } catch { } #endregion UIPbStatus(50); if (version.DoClean) { #region 删除非当前版本文件 List file = FileTool.GetAllFile(R.AppPath); if (!ListTool.IsNullOrEmpty(file)) { foreach (var f in file) { int c = version.FileList.Where(x => x.File == "\\" + f.Replace(R.AppPath, "")).Count(); if (c == 0) { try { File.Delete(f); } catch { } } } Thread.Sleep(R.cst.WAIT_TIME); } #endregion #region 删除空文件夹 List path = DirTool.GetAllPath(R.AppPath); if (!ListTool.IsNullOrEmpty(path)) { path = path.OrderByDescending(x => x).ToList(); foreach (var p in path) { if (Directory.GetFiles(p).Length == 0 && Directory.GetDirectories(p).Length == 0) { if (Directory.Exists(p)) { try { Directory.Delete(p); } catch { } } } Thread.Sleep(R.cst.WAIT_TIME); } } #endregion } UIPbStatus(100); Step = 5; } /// /// 更新开始结束程序 /// void BeginCloseProcess() { int percent = 1; if (!ListTool.IsNullOrEmpty(version.BeginCloseProcess)) { foreach (var p in version.BeginCloseProcess) { Thread.Sleep(R.cst.WAIT_TIME); UIPbStatus((int)((double)(percent++) / version.BeginCloseProcess.Count() * 100)); if (!string.IsNullOrWhiteSpace(p)) ProcessTool.KillProcess(p); } } Step = 2; } /// /// 更新结束启动程序 /// void EndRunProcess() { int percent = 1; if (!ListTool.IsNullOrEmpty(version.EndRunProcess)) { foreach (var p in version.EndRunProcess) { Thread.Sleep(R.cst.WAIT_TIME); UIPbStatus((int)((double)(percent++) / version.EndRunProcess.Count() * 100)); if (!string.IsNullOrWhiteSpace(p)) ProcessTool.StartProcess(Path.Combine(R.AppPath, p)); } } } #endregion #region UI刷新 /// /// 在DgvFileList中添加一条新纪录 /// /// void UIDgvFileListAdd(params object[] values) { this.BeginInvoke(new Action(() => { if (values != null) { DgvFileList.Rows.Add(values); DgvFileList.FirstDisplayedScrollingRowIndex = DgvFileList.RowCount - 1; UIPbStatus((int)((double)(int)(values[0]) / version.FileList.Count * 100)); } })); } /// /// 更新DgvFileList控件中的记录 /// /// /// /// void UIDgvFileListUpdate(int row, string cell, string value) { this.BeginInvoke(new Action(() => { DgvFileList.Rows[row].Cells[cell].Value = value; if (version.FileList.Count > 5) DgvFileList.FirstDisplayedScrollingRowIndex = (row - 5) > 0 ? (row - 5) : 0; UIPbStatus((int)((double)(row + 1) / version.FileList.Count * 100)); })); } /// /// 设置ProgressBar的进度百分比 /// /// void UIPbStatus(int percent) { Invoke(new Action(() => { PbStatus.Value = percent; })); } /// /// 更新LbStatus状态信息文本 /// /// void UILbStatus(string msg) { Invoke(new Action(() => { LbStatus.Text = msg; })); } void UIClose() { Invoke(new Action(() => { Close(); })); } void UIShowRetry() { Invoke(new Action(() => { LbRetry.Visible = true; })); } #endregion #region 控件事件 private void LbStatus_DoubleClick(object sender, EventArgs e) { if (Height < (SmallHeight + ((LargeHeight - SmallHeight) / 2))) { Height = LargeHeight; } else { Height = SmallHeight; } } private void LbRetry_Click(object sender, EventArgs e) { UpdateTask(); } #endregion } }