AutoUpdater 实现一个简易的自动升级工具

AutoUpdater 实现一个简易的自动升级工具实现一个简易的自动升级工具 在保持某 XX 系统不做改动的情况下 加入自动更行功能 考虑使用外部程序作为启动器 先检测版本执行更新 再去 launch 某 XX 系统的主程序 并且要支持某 XX 系统主动运行该自动更新工具也可以完成更新 简单介绍一下自动升级要做的事 注 适用于支持部分文件升级的系统

大家好,我是讯享网,很高兴认识大家。

实现一个简易的自动升级工具

在保持某XX系统不做改动的情况下,加入自动更行功能。

考虑使用外部程序作为启动器,先检测版本执行更新,再去launch某XX系统的主程序。并且要支持某XX系统主动运行该自动更新工具也可以完成更新。

 

简单介绍一下自动升级要做的事:

注:适用于支持部分文件升级的系统。

1.服务端提供文件下载服务,提供加密后的自动更新文件清单内容。

2.客户端获取自动更新文件清单,并解密内容,比对主版本,比对文件MD5,关闭主程序,下载需要的文件,覆盖文件到最新版本,重启主程序。

 

服务端清单文件配置工具,生成清单文件:

清单文件部分内容经过DES加密再存储。

 /// <summary> /// 清单文件 读取并解析XML到对象(C#客户端解析XML可参照此处) /// </summary> /// <param name="modelData"></param> /// <param name="filePath"></param> private void ReadAutoUpdateMapsXml(UptBaseModel modelData, string filePath) { if (!File.Exists(filePath)) return; var tempModel = XmlHelper.Deserialize<UptBaseModel>(File.ReadAllText(filePath)); if (tempModel != null) { modelData.version = tempModel.version; modelData.description = tempModel.description; modelData.server = EncryptParse.DESDecrypt(tempModel.server ?? "", EncryptParse.GenerateDESKey(tempModel.version ?? "")); if (tempModel.files != null && tempModel.files.Count > 0) { modelData.count = tempModel.files.Count; foreach (var item in tempModel.files) { //DES解密信息 item.fileName = EncryptParse.DESDecrypt(item.fileName ?? "", EncryptParse.GenerateDESKey(item.hash1)); item.filePath = EncryptParse.DESDecrypt(item.filePath ?? "", EncryptParse.GenerateDESKey(item.hash1)); item.fileDrect = EncryptParse.DESDecrypt(item.fileDrect ?? "", EncryptParse.GenerateDESKey(item.hash1)); item.urlDrect = EncryptParse.DESDecrypt(item.urlDrect ?? "", EncryptParse.GenerateDESKey(item.hash1)); } modelData.files.Clear(); modelData.files.AddRange(tempModel.files); } } else { modelData.version = "1.0.0.0"; modelData.description = ""; modelData.files.Clear(); } } /// <summary> /// 清单文件 加密并保存内容到XML /// </summary> /// <param name="modelData"></param> /// <param name="toPath"></param> private void SaveAutoUpdateMapsXml(UptBaseModel modelData, string toPath) { var tempModel = new UptBaseModel(); tempModel.version = modelData.version; tempModel.description = modelData.description; tempModel.server = EncryptParse.DESEncrypt(modelData.server ?? "", EncryptParse.GenerateDESKey(modelData.version ?? "")); foreach (var item in modelData.files) { var info = new FileInfoModel(); info.hash1 = item.hash1; info.fileVer = item.fileVer; info.fileBytes = item.fileBytes; info.lastWTime = item.lastWTime; //DES加密信息 info.fileName = EncryptParse.DESEncrypt(item.fileName ?? "", EncryptParse.GenerateDESKey(item.hash1)); info.filePath = EncryptParse.DESEncrypt(item.filePath ?? "", EncryptParse.GenerateDESKey(item.hash1)); info.fileDrect = EncryptParse.DESEncrypt(item.fileDrect ?? "", EncryptParse.GenerateDESKey(item.hash1)); info.urlDrect = EncryptParse.DESEncrypt(item.urlDrect ?? "", EncryptParse.GenerateDESKey(item.hash1)); tempModel.files.Add(info); } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(XmlHelper.Serialize(tempModel, true, true)); xmlDoc.Save(toPath); } 

讯享网

客户端自动更新程序,获取清单内容、下载文件:

这里直接使用http下载清单文件。

下载步骤:获取清单文件,通过DES解密内容,获得最新文件下载链接及目标路径,再比对MD5并下载到临时文件夹。


讯享网

更新步骤:关闭待更新应用主程序,覆盖临时文件夹中的文件到应用程序目录,删除临时文件夹,重启应用主程序。

讯享网 /// <summary> /// 获取清单文件链接地址 /// </summary> /// <param name="serverUrl">文件父目录</param> /// <param name="arrgs">命令参数</param> /// <returns></returns> public static string GetAutoUpdateMapsXmlServerUrl(string serverUrl, string[] arrgs) { serverUrl = Common.ServerUrl; var fileUrl = serverUrl + "/" + _AutoUpdateMapsXmlName; if (arrgs != null && arrgs.Length > 0) { //var url = _arrgs.Where(x => x.ToLower().StartsWith("http:")).FirstOrDefault(); var url = string.Empty; foreach (var v in arrgs) { if (v.ToLower().StartsWith("http:", StringComparison.OrdinalIgnoreCase)) url = v; if (v.ToLower().StartsWith("https:", StringComparison.OrdinalIgnoreCase)) url = v; } if (string.IsNullOrEmpty(url) == false) { serverUrl = url; fileUrl = serverUrl + "/" + _AutoUpdateMapsXmlName; } if (url?.ToLower().LastIndexOf(".xml") > 0) { fileUrl = url; } } return new Uri(fileUrl).ToString(); } ///<summary> /// HTTP读取文件文本内容 /// </summary> /// <param name="fileUrl">文件链接地址</param> public static string DownloadAutoUpdateMapsXmlText(string fileUrl) { HttpWebRequest resq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(fileUrl); HttpWebResponse resp = (System.Net.HttpWebResponse)resq.GetResponse(); //判断服务器未响应 if (resp.StatusCode != HttpStatusCode.OK) { throw new Exception("文件内容地址响应失败"); } Stream st = resp.GetResponseStream(); Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); StreamReader reader = new StreamReader(st, encode); return reader.ReadToEnd(); } /// <summary> /// 读取并解析XML到对象 /// </summary> /// <param name="targetXml"></param> public static UptBaseModel ReadAutoUpdateMapsXml(string targetXml) { UptBaseModel modelData = new UptBaseModel(); if (string.IsNullOrEmpty(targetXml)) return modelData; var tempModel = XmlHelper.Deserialize<UptBaseModel>(targetXml); if (tempModel != null) { modelData.version = tempModel.version; modelData.description = tempModel.description; //modelData.server = EncryptParse.DESDecrypt(tempModel.server ?? "", EncryptParse.GenerateDESKey(tempModel.version ?? "")); if (tempModel.files != null && tempModel.files.Count > 0) { modelData.count = tempModel.files.Count; foreach (var item in tempModel.files) { //DES解密信息 item.fileName = EncryptParse.DESDecrypt(item.fileName, EncryptParse.GenerateDESKey(item.hash1)); item.filePath = EncryptParse.DESDecrypt(item.filePath, EncryptParse.GenerateDESKey(item.hash1)); item.fileDrect = EncryptParse.DESDecrypt(item.fileDrect, EncryptParse.GenerateDESKey(item.hash1)); item.urlDrect = EncryptParse.DESDecrypt(item.urlDrect ?? "", EncryptParse.GenerateDESKey(item.hash1)); } modelData.files.Clear(); modelData.files.AddRange(tempModel.files); } } else { modelData.version = "1.0.0.0"; modelData.description = ""; modelData.files.Clear(); } return modelData; } /// <summary> /// 创建下载任务 /// </summary> /// <param name="modelBase"></param> /// <param name="tempPath"></param> /// <param name="downloadProgressChangedEventHandler"></param> /// <param name="asyncCompletedEventHandler"></param> public static int CreatDownloadTasks(UptBaseModel modelBase, string tempPath, DownloadProgressChangedEventHandler downloadProgressChangedEventHandler = null, AsyncCompletedEventHandler asyncCompletedEventHandler = null) { if (modelBase != null && modelBase.files != null && modelBase.files.Count > 0) { if (string.IsNullOrEmpty(tempPath)) tempPath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "patch"); //默认文件缓存路径 //缓存目录文件夹不存在则创建 if (Directory.Exists(tempPath) == false) { Directory.CreateDirectory(tempPath); } foreach (var item in modelBase.files) { var toPath = Path.Combine(tempPath, item.fileDrect); //目标文件夹不存在则创建 if (Directory.Exists(Path.GetDirectoryName(toPath)) == false) { Directory.CreateDirectory(Path.GetDirectoryName(toPath)); } //比对文件MD5码 if (File.Exists(toPath)) { var nowHash = EncryptParse.GetFileMD5Hash(toPath); if (nowHash == item.hash1) continue; } item.targetPath = toPath; //开始创建连接下载 WebClient client = new WebClient(); if (downloadProgressChangedEventHandler != null) client.DownloadProgressChanged += downloadProgressChangedEventHandler; if (asyncCompletedEventHandler != null) client.DownloadFileCompleted += asyncCompletedEventHandler; client.DownloadFileAsync(new Uri(item.urlDrect), toPath, item); modelBase.updateCount++; } } return modelBase.updateCount; } 

效果图:

清单配置工具:

自动更新程序:

源代码奉上:

AutoUpdater.rar

小讯
上一篇 2025-02-27 20:22
下一篇 2025-03-27 17:32

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/16694.html