UpdateManage.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Security.Cryptography;
  7. using System.Text;
  8. //----------------------------------------------------------------
  9. //Module Name: $safeprojectname$
  10. //Purpose:
  11. //CopyRight: Muchinfo
  12. //History:
  13. //----------------------------------------------------------------
  14. //DateTime 2016/1/5 15:51:07
  15. //Author
  16. //Description Create
  17. //----------------------------------------------------------------
  18. using System.Windows;
  19. using System.Windows.Controls;
  20. namespace Muchinfo.MTPClient.Update
  21. {
  22. public class UpdateManage
  23. {
  24. private const string resource = "Config";
  25. private const string DefaultFolder = "DefaultFolder";
  26. private const string c_chartUpdateFile = "FinancePrice.dll"; ////图表控件
  27. private const string c_chartRegitFile = "regchart.bat";///注册图表控件的文件路径
  28. ///图表路径目录
  29. public static string ChartPathDir
  30. {
  31. get
  32. {
  33. return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "COM");
  34. }
  35. }
  36. /// <summary>
  37. /// 是否有图表更新
  38. /// </summary>
  39. public static bool IsChartUpdate { get; set; }
  40. /// <summary>
  41. /// 执行判断更新
  42. /// </summary>
  43. /// <param name="updateBasePath">更新服务的路径</param>
  44. public static UpdateInfo RunUpdate(string updatePath, string memberCode)
  45. {
  46. UpdateInfo remoteInfo;
  47. string parentPath = AppDomain.CurrentDomain.BaseDirectory;
  48. var localFileInfo = LoadLocalConfig();
  49. bool mainUpdate = CheckMainAppUpdate(updatePath, memberCode, localFileInfo, out remoteInfo);
  50. if (mainUpdate)
  51. {
  52. var tipWindow = new TipsWindow("检测到交易端有新版本是否更新?");
  53. var result = tipWindow.ShowDialog();
  54. // var result = MessageBox.Show(" 检测到交易端有新版本是否更新?","更新提示" , MessageBoxButton.YesNo);
  55. if (result == true)
  56. {
  57. var processes = Process.GetProcessesByName(remoteInfo.StartAppName.Replace(".exe", string.Empty));
  58. foreach (var process in processes)
  59. {
  60. process.Kill();
  61. }
  62. return remoteInfo;
  63. }
  64. }
  65. return null;
  66. }
  67. /// <summary>
  68. /// 加载本地配置文件,如不存在则生成
  69. /// </summary>
  70. /// <returns></returns>
  71. public static UpdateInfo LoadLocalConfig()
  72. {
  73. var updateHelper = new UpdateHelper();
  74. UpdateInfo updateInfo;
  75. string parentPath = AppDomain.CurrentDomain.BaseDirectory;
  76. var configPath = string.Format("{0}\\{1}.xml", parentPath, typeof(UpdateInfo).Name);
  77. if (File.Exists(configPath)) //本地更新配置文件存在
  78. {
  79. updateInfo =
  80. updateHelper.LoadUpdateConfig(configPath); //todo:读取失败应生成
  81. }
  82. else
  83. {
  84. updateInfo = updateHelper.CreateUpdateInfoFile(parentPath);
  85. }
  86. return updateInfo;
  87. }
  88. /// <summary>
  89. /// 检查主程序有没有更新
  90. /// </summary>
  91. /// <param name="updatePath">更新基目录文件</param>
  92. /// <param name="localConfigExists">是否有本地配置</param>
  93. /// <param name="updateInfo">服务端更新配置</param>
  94. /// <returns></returns>
  95. public static bool CheckMainAppUpdate(string updatePath, string memberCode, UpdateInfo localfileInfo, out UpdateInfo updateFileInfo)
  96. {
  97. updateFileInfo = new UpdateInfo();
  98. var updateHelper = new UpdateHelper();
  99. var remoteFileInfo = updateHelper.LoadUpdateConfig(string.Format("{0}/{1}.xml", updatePath, typeof(UpdateInfo).Name));
  100. if (remoteFileInfo.UpdateFiles == null || !remoteFileInfo.UpdateFiles.Any())
  101. {
  102. return false;
  103. }
  104. var memberPath = string.Empty;
  105. if (!string.IsNullOrEmpty(remoteFileInfo.ResourceDir)) ////没有个性化资源
  106. {
  107. if (string.IsNullOrWhiteSpace(memberCode)) ////没有会员代码
  108. {
  109. var resourceDir = Path.Combine(remoteFileInfo.ResourceDir, ""); ////过滤会员资源
  110. remoteFileInfo.UpdateFiles =
  111. remoteFileInfo.UpdateFiles.Where((item) => item.FilePath.StartsWith(resourceDir)).ToList();
  112. }
  113. else
  114. {
  115. memberPath = Path.Combine(remoteFileInfo.ResourceDir, memberCode); ////取会员资源
  116. var updateFiles = new List<UpdateFile>();
  117. foreach (var item in updateFileInfo.UpdateFiles)
  118. {
  119. if (item.FilePath.StartsWith(memberPath))
  120. {
  121. updateFiles.Add(item);
  122. }
  123. }
  124. remoteFileInfo.UpdateFiles = updateFiles;
  125. }
  126. }
  127. if (localfileInfo == null || localfileInfo.UpdateFiles == null || !localfileInfo.UpdateFiles.Any()) ////本地没有文件
  128. {
  129. updateFileInfo = remoteFileInfo;
  130. return true;
  131. }
  132. else
  133. {
  134. ////todo:比较文件MD5。生成升级的文件列表
  135. remoteFileInfo.UpdateFiles = CompareUpdateFile(remoteFileInfo, localfileInfo, memberPath);
  136. updateFileInfo = remoteFileInfo;
  137. #if DEBUG
  138. UpdateHelper.SaveStaticUpdateXml(updateFileInfo, AppDomain.CurrentDomain.BaseDirectory + "\\test.xml");
  139. #endif
  140. return remoteFileInfo.UpdateFiles.Any(); ////是否有更新的文件
  141. }
  142. }
  143. /// <summary>
  144. /// /
  145. /// </summary>
  146. /// <param name="serverInfo"></param>
  147. /// <param name="localinfo"></param>
  148. /// <param name="memberPath">会员代码前的升级文件</param>
  149. /// <returns></returns>
  150. public static List<UpdateFile> CompareFileResourceUpdate(UpdateInfo serverInfo, UpdateInfo localinfo,
  151. string memberPath)
  152. {
  153. var localFilesInfo = localinfo.UpdateFiles.ToDictionary((file) => file.FilePath);
  154. var serverfilesInfo = serverInfo.UpdateFiles.ToDictionary((item) => item.FilePath);
  155. var updateFiles = new List<UpdateFile>();
  156. foreach (var fileKey in serverfilesInfo.Keys)
  157. {
  158. if (localFilesInfo.ContainsKey(fileKey))
  159. {
  160. if (!serverfilesInfo[fileKey].MD5Code.Equals(localFilesInfo[fileKey].MD5Code,StringComparison.InvariantCultureIgnoreCase))
  161. {
  162. updateFiles.Add(serverfilesInfo[fileKey]);
  163. }
  164. }
  165. else
  166. {
  167. updateFiles.Add(serverfilesInfo[fileKey]);
  168. }
  169. }
  170. return updateFiles;
  171. }
  172. /// <summary>
  173. /// 比较更新的文件
  174. /// </summary>
  175. public static List<UpdateFile> CompareUpdateFile(UpdateInfo serverInfo, UpdateInfo localinfo, string memberPath)
  176. {
  177. var localFilesInfo = localinfo.UpdateFiles.ToDictionary((file) => file.FilePath.ToLower());
  178. var serverfilesInfo = serverInfo.UpdateFiles.ToDictionary((item) => item.FilePath.ToLower());
  179. ////移除不更新的文件
  180. var keyItems= serverfilesInfo.Keys.ToList();
  181. var unUpdateList = UnUpdateList();
  182. try
  183. {
  184. foreach (var unFile in unUpdateList)
  185. {
  186. foreach (var keyItem in keyItems)
  187. {
  188. var keys = keyItem.Split('\\');
  189. if (keys.Any())
  190. {
  191. var fileNameExit = keys[keys.Length - 1];
  192. var fileName = fileNameExit.Substring(0, fileNameExit.LastIndexOf('.'));
  193. if (fileName.Equals(unFile))
  194. {
  195. serverfilesInfo.Remove(keyItem);
  196. continue;
  197. }
  198. }
  199. }
  200. }
  201. }
  202. catch (Exception ex)
  203. {
  204. }
  205. var updateFiles = new List<UpdateFile>();
  206. #if DEBUG
  207. UpdateHelper.SaveStaticUpdateXml(localinfo, AppDomain.CurrentDomain.BaseDirectory + "\\localinfo.xml");
  208. UpdateHelper.SaveStaticUpdateXml(serverInfo, AppDomain.CurrentDomain.BaseDirectory + "\\serverInfo.xml");
  209. #endif
  210. foreach (var fileKey in serverfilesInfo.Keys)
  211. {
  212. var keyItem = fileKey.ToLower();
  213. if (!string.IsNullOrWhiteSpace(memberPath))
  214. {
  215. keyItem = fileKey.Replace(memberPath, string.Empty); ////会员资源与本地的路径要一致
  216. }
  217. if (localFilesInfo.ContainsKey(keyItem.ToLower()))
  218. {
  219. if (!serverfilesInfo[keyItem].MD5Code.Equals(localFilesInfo[keyItem].MD5Code, StringComparison.InvariantCultureIgnoreCase))
  220. {
  221. updateFiles.Add(serverfilesInfo[keyItem]);
  222. bool chartUpdate = keyItem.Contains(c_chartUpdateFile.ToLower());
  223. if (chartUpdate)
  224. {
  225. IsChartUpdate = true; ////有图表控件更新
  226. }
  227. }
  228. }
  229. else
  230. {
  231. bool chartUpdate = keyItem.Contains(c_chartUpdateFile.ToLower());
  232. if (chartUpdate)
  233. {
  234. IsChartUpdate = true; ////有图表控件更新
  235. }
  236. updateFiles.Add(serverfilesInfo[keyItem]);
  237. }
  238. }
  239. return updateFiles;
  240. }
  241. /// <summary>
  242. /// 计算文件MD5
  243. /// </summary>
  244. /// <param name="fileInfo"></param>
  245. /// <returns></returns>
  246. public static string GetFileMD5Code(FileInfo fileInfo)
  247. {
  248. using (FileStream fs = File.OpenRead(fileInfo.FullName)) //new FileStream(fileInfo.FullName, FileMode.Open))
  249. {
  250. System.Security.Cryptography.MD5 md5 = new MD5CryptoServiceProvider();
  251. byte[] retval = md5.ComputeHash(fs);
  252. fs.Close();
  253. var sbBuilder = new StringBuilder();
  254. for (int i = 0; i < retval.Length; i++)
  255. {
  256. sbBuilder.Append(retval[i].ToString("x2"));
  257. }
  258. return sbBuilder.ToString().ToUpper();
  259. }
  260. }
  261. /// <summary>
  262. /// 注册图表控件
  263. /// </summary>
  264. public static void RegisterChart()
  265. {
  266. if (IsChartUpdate)
  267. {
  268. var regPath = Path.Combine(ChartPathDir, c_chartRegitFile);
  269. if (!File.Exists(regPath))
  270. {
  271. var chartfile = Path.Combine(ChartPathDir, c_chartUpdateFile);
  272. var sbuilder=new StringBuilder();
  273. sbuilder.AppendLine(string.Format("regsvr32 \"{0}\" /u", chartfile));
  274. sbuilder.AppendLine(string.Format("regsvr32 \"{0}\" ", chartfile));
  275. using (var fsStream = new FileStream(regPath,FileMode.CreateNew))
  276. {
  277. var text = new StreamWriter(fsStream, Encoding.Default);
  278. text.Write(sbuilder.ToString());
  279. text.Close();
  280. fsStream.Close();
  281. }
  282. }
  283. var startInfo = new System.Diagnostics.ProcessStartInfo(regPath);
  284. startInfo.WindowStyle = ProcessWindowStyle.Hidden;
  285. startInfo.UseShellExecute = false;
  286. startInfo.CreateNoWindow = true;
  287. //startInfo.StandardOutputEncoding = Encoding.UTF8;
  288. Process process = Process.Start(startInfo);
  289. process.WaitForExit(7000);
  290. // Process process = Process.Start(regPath);
  291. }
  292. }
  293. /// <summary>
  294. ///不检查更新的文件列表
  295. /// </summary>
  296. /// <returns></returns>
  297. public static List<string> UnUpdateList()
  298. {
  299. var updateList = new List<string>();
  300. updateList.Add("contresxs");
  301. updateList.Add("errorcodes");
  302. return updateList;
  303. }
  304. }
  305. }