Form1.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. using Azylee.Core.DataUtils.CollectionUtils;
  2. using Azylee.Core.IOUtils.DirUtils;
  3. using Azylee.Core.IOUtils.FileUtils;
  4. using Azylee.Core.Plus.DataUtils.JsonUtils;
  5. using Azylee.Core.ProcessUtils;
  6. using Azylee.YeahWeb.FTPUtils;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. using Version.Update.Commons;
  15. using Version.Update.Models;
  16. namespace Version.Update
  17. {
  18. public partial class Form1 : Form
  19. {
  20. string downloadPath = "";
  21. VersionModel version;
  22. int Step = 1, Error = 1;
  23. int SmallHeight = 146;
  24. int LargeHeight = 420;
  25. public Form1()
  26. {
  27. InitializeComponent();
  28. Height = SmallHeight;
  29. LbRetry.Visible = false;
  30. }
  31. private void Form1_Load(object sender, EventArgs e)
  32. {
  33. UpdateTask();
  34. }
  35. #region 更新功能
  36. /// <summary>
  37. /// 完整的更新任务
  38. /// </summary>
  39. void UpdateTask()
  40. {
  41. LbRetry.Visible = false;
  42. Step = 1;
  43. Error = 1;
  44. string folder = Guid.NewGuid().ToString();
  45. downloadPath = R.AppPath + @"Temp\Update\" + folder;
  46. Task.Factory.StartNew(() =>
  47. {
  48. UILbStatus("[准备] 正在读取版本文件...");
  49. if (GetVersion())
  50. {
  51. UILbStatus("[准备] 正在读取版本文件...[完成]");
  52. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  53. if (Step == 1)
  54. {
  55. UILbStatus("[1/5] 正在退出相关程序...");
  56. BeginCloseProcess();
  57. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  58. UILbStatus("[1/5] 正在退出相关程序...[完成]");
  59. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  60. }
  61. if (Step == 2)
  62. {
  63. UILbStatus("[2/5] 正在下载新版本的文件...");
  64. DownloadFile(downloadPath);
  65. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  66. UILbStatus("[2/5] 正在下载新版本的文件...[完成]");
  67. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  68. }
  69. if (Step == 3)
  70. {
  71. UILbStatus("[3/5] 正在更新文件...");
  72. UpdateFile(downloadPath);
  73. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  74. UILbStatus("[3/5] 正在更新文件...[完成]");
  75. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  76. }
  77. if (Step == 4)
  78. {
  79. UILbStatus("[4/5] 正在清理冗余文件...");
  80. CleanFile();
  81. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  82. UILbStatus("[4/5] 正在清理冗余文件...[完成]");
  83. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  84. }
  85. if (Step == 5)
  86. {
  87. UILbStatus("[5/5] 准备启动程序...");
  88. EndRunProcess();
  89. UILbStatus("[5/5] 准备启动程序...[完成]");
  90. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  91. }
  92. if (Error > 0)
  93. {
  94. UILbStatus("[更新成功 即将退出]");
  95. Thread.Sleep(R.cst.STEP_WAIT_TIME);
  96. UIClose();
  97. }
  98. else
  99. {
  100. UILbStatus("[更新异常 请检查并解决故障后 重新更新]");
  101. UIShowRetry();
  102. }
  103. }
  104. else
  105. {
  106. UILbStatus("[结束] 未发现新版本...");
  107. MessageBox.Show("您已经是最新版本了。", "完成");
  108. UIClose();
  109. }
  110. });
  111. }
  112. /// <summary>
  113. /// 获取版本配置文件
  114. /// </summary>
  115. /// <returns></returns>
  116. bool GetVersion()
  117. {
  118. version = JsonTool.ToObjFromFile<VersionModel>(R.VersionFile);
  119. if (version != null)
  120. {
  121. try
  122. {
  123. int num = 1;
  124. foreach (var item in version.FileList)
  125. {
  126. UIDgvFileListAdd(new object[] { num++, Path.GetFileName(item.File) });
  127. Thread.Sleep(R.cst.WAIT_TIME);
  128. }
  129. return true;
  130. }
  131. catch (Exception e) { }
  132. }
  133. return false;
  134. }
  135. /// <summary>
  136. /// 下载程序文件
  137. /// </summary>
  138. /// <returns></returns>
  139. bool DownloadFile(string downloadPath)
  140. {
  141. if (DirTool.Create(downloadPath))
  142. {
  143. FileCodeTool fcode = new FileCodeTool();
  144. for (int i = 0; i < version.FileList.Count; i++)
  145. {
  146. string fileName = Path.GetFileName(version.FileList[i].File);
  147. string sourceFile = version.ServerPath + version.FileList[i].File;
  148. string destFile = downloadPath + version.FileList[i].File;
  149. string destPath = destFile.Substring(0, destFile.Length - fileName.Length);
  150. if (DirTool.Create(destPath))
  151. {
  152. if (File.Exists(R.AppPath + version.FileList[i].File) &&
  153. version.FileList[i].MD5 == fcode.GetMD5(R.AppPath + version.FileList[i].File))
  154. {
  155. UIDgvFileListUpdate(i, "ColDown", R.cst.FILE_JUMP);
  156. }
  157. else
  158. {
  159. FtpTool ftp = new FtpTool(R.FtpIp, R.FtpAccount, R.FtpPassword);
  160. if (!ftp.DownloadFile(sourceFile, destPath))
  161. if (!ftp.DownloadFile(sourceFile, destPath))
  162. if (!ftp.DownloadFile(sourceFile, destPath))
  163. {
  164. MessageBox.Show("更新文件无法被下载,请检查网络重试,谢谢。", "网络故障");
  165. Step = 5;
  166. Error = -201;
  167. return false;
  168. }
  169. UIDgvFileListUpdate(i, "ColDown", R.cst.FILE_SUCC);
  170. }
  171. }
  172. else
  173. {
  174. UIDgvFileListUpdate(i, "ColDown", R.cst.FILE_FAIL);
  175. }
  176. Thread.Sleep(R.cst.WAIT_TIME);
  177. }
  178. }
  179. Step = 3;
  180. return true;
  181. }
  182. /// <summary>
  183. /// 更新程序文件
  184. /// </summary>
  185. /// <returns></returns>
  186. bool UpdateFile(string downloadPath)
  187. {
  188. for (int i = 0; i < version.FileList.Count; i++)
  189. {
  190. string fileName = Path.GetFileName(version.FileList[i].File);
  191. string sourceFile = downloadPath + version.FileList[i].File;
  192. string destFile = R.AppPath + version.FileList[i].File;
  193. string destPath = destFile.Substring(0, destFile.Length - fileName.Length);
  194. if (DirTool.Create(destPath))
  195. {
  196. try
  197. {
  198. if (File.Exists(sourceFile))
  199. {
  200. File.Copy(sourceFile, destFile, true);
  201. UIDgvFileListUpdate(i, "ColUpdate", R.cst.FILE_SUCC);
  202. }
  203. else
  204. {
  205. UIDgvFileListUpdate(i, "ColUpdate", R.cst.FILE_JUMP);
  206. }
  207. }
  208. catch (Exception e)
  209. {
  210. UIDgvFileListUpdate(i, "ColUpdate", R.cst.FILE_FAIL);
  211. }
  212. }
  213. else
  214. {
  215. UIDgvFileListUpdate(i, "ColBack", R.cst.FILE_FAIL);
  216. }
  217. Thread.Sleep(R.cst.WAIT_TIME);
  218. }
  219. Step = 4;
  220. return false;
  221. }
  222. /// <summary>
  223. /// 清理之前版本遗留文件及空文件夹
  224. /// </summary>
  225. /// <returns></returns>
  226. void CleanFile()
  227. {
  228. UIPbStatus(0);
  229. #region 删除下载的更新文件和版本文件
  230. try
  231. {
  232. Directory.Delete(R.AppPath + @"Temp\Update\", true);
  233. File.Delete(R.VersionFile);
  234. }
  235. catch { }
  236. #endregion
  237. UIPbStatus(50);
  238. if (version.DoClean)
  239. {
  240. #region 删除非当前版本文件
  241. List<string> file = FileTool.GetAllFile(R.AppPath);
  242. if (!ListTool.IsNullOrEmpty(file))
  243. {
  244. foreach (var f in file)
  245. {
  246. int c = version.FileList.Where(x => x.File == "\\" + f.Replace(R.AppPath, "")).Count();
  247. if (c == 0)
  248. {
  249. try { File.Delete(f); } catch { }
  250. }
  251. }
  252. Thread.Sleep(R.cst.WAIT_TIME);
  253. }
  254. #endregion
  255. #region 删除空文件夹
  256. List<string> path = DirTool.GetAllPath(R.AppPath);
  257. if (!ListTool.IsNullOrEmpty(path))
  258. {
  259. path = path.OrderByDescending(x => x).ToList();
  260. foreach (var p in path)
  261. {
  262. if (Directory.GetFiles(p).Length == 0 && Directory.GetDirectories(p).Length == 0)
  263. {
  264. if (Directory.Exists(p))
  265. {
  266. try { Directory.Delete(p); } catch { }
  267. }
  268. }
  269. Thread.Sleep(R.cst.WAIT_TIME);
  270. }
  271. }
  272. #endregion
  273. }
  274. UIPbStatus(100);
  275. Step = 5;
  276. }
  277. /// <summary>
  278. /// 更新开始结束程序
  279. /// </summary>
  280. void BeginCloseProcess()
  281. {
  282. int percent = 1;
  283. if (!ListTool.IsNullOrEmpty(version.BeginCloseProcess))
  284. {
  285. foreach (var p in version.BeginCloseProcess)
  286. {
  287. Thread.Sleep(R.cst.WAIT_TIME);
  288. UIPbStatus((int)((double)(percent++) / version.BeginCloseProcess.Count() * 100));
  289. if (!string.IsNullOrWhiteSpace(p))
  290. ProcessTool.Kill(p);
  291. }
  292. }
  293. Step = 2;
  294. }
  295. /// <summary>
  296. /// 更新结束启动程序
  297. /// </summary>
  298. void EndRunProcess()
  299. {
  300. int percent = 1;
  301. if (!ListTool.IsNullOrEmpty(version.EndRunProcess))
  302. {
  303. foreach (var p in version.EndRunProcess)
  304. {
  305. Thread.Sleep(R.cst.WAIT_TIME);
  306. UIPbStatus((int)((double)(percent++) / version.EndRunProcess.Count() * 100));
  307. if (!string.IsNullOrWhiteSpace(p))
  308. ProcessTool.Start(Path.Combine(R.AppPath, p));
  309. }
  310. }
  311. }
  312. #endregion
  313. #region UI刷新
  314. /// <summary>
  315. /// 在DgvFileList中添加一条新纪录
  316. /// </summary>
  317. /// <param name="values"></param>
  318. void UIDgvFileListAdd(params object[] values)
  319. {
  320. this.BeginInvoke(new Action(() =>
  321. {
  322. if (values != null)
  323. {
  324. DgvFileList.Rows.Add(values);
  325. DgvFileList.FirstDisplayedScrollingRowIndex = DgvFileList.RowCount - 1;
  326. UIPbStatus((int)((double)(int)(values[0]) / version.FileList.Count * 100));
  327. }
  328. }));
  329. }
  330. /// <summary>
  331. /// 更新DgvFileList控件中的记录
  332. /// </summary>
  333. /// <param name="row"></param>
  334. /// <param name="cell"></param>
  335. /// <param name="value"></param>
  336. void UIDgvFileListUpdate(int row, string cell, string value)
  337. {
  338. this.BeginInvoke(new Action(() =>
  339. {
  340. DgvFileList.Rows[row].Cells[cell].Value = value;
  341. if (version.FileList.Count > 5)
  342. DgvFileList.FirstDisplayedScrollingRowIndex = (row - 5) > 0 ? (row - 5) : 0;
  343. UIPbStatus((int)((double)(row + 1) / version.FileList.Count * 100));
  344. }));
  345. }
  346. /// <summary>
  347. /// 设置ProgressBar的进度百分比
  348. /// </summary>
  349. /// <param name="percent"></param>
  350. void UIPbStatus(int percent)
  351. {
  352. Invoke(new Action(() =>
  353. {
  354. PbStatus.Value = percent;
  355. }));
  356. }
  357. /// <summary>
  358. /// 更新LbStatus状态信息文本
  359. /// </summary>
  360. /// <param name="msg"></param>
  361. void UILbStatus(string msg)
  362. {
  363. Invoke(new Action(() =>
  364. {
  365. LbStatus.Text = msg;
  366. }));
  367. }
  368. void UIClose()
  369. {
  370. Invoke(new Action(() =>
  371. {
  372. Close();
  373. }));
  374. }
  375. void UIShowRetry()
  376. {
  377. Invoke(new Action(() => { LbRetry.Visible = true; }));
  378. }
  379. #endregion
  380. #region 控件事件
  381. private void LbStatus_DoubleClick(object sender, EventArgs e)
  382. {
  383. if (Height < (SmallHeight + ((LargeHeight - SmallHeight) / 2)))
  384. {
  385. Height = LargeHeight;
  386. }
  387. else
  388. {
  389. Height = SmallHeight;
  390. }
  391. }
  392. private void LbRetry_Click(object sender, EventArgs e)
  393. {
  394. UpdateTask();
  395. }
  396. #endregion
  397. }
  398. }