/// <summary> /// 根据一个文件夹生成xml的配置文件(或zip文件) /// </summary> /// <param name="dirPath">要计算的文件夹</param> /// <param name="urlDom">url文件服务器上的路径,形如http://mr.xuexuesoft.com:8010/UpdateFile/</param> /// <param name="xmlPath">最后的结果xml文件路径(支持.xml和.zip)</param> public static void CreatConfigFileWithXml(string dirPath, string urlDom, string xmlPath) { OriginFolder folder = new OriginFolder(); DirectoryInfo di = new DirectoryInfo(dirPath); FileInfo[] fis = di.GetFiles("*", SearchOption.AllDirectories); for (int i = 0; i < fis.Length; i++) { //遍历每一个文件 FileInfo fi = fis[i]; FileItem fileItem = new FileItem() { size = fi.Length }; fileItem.relativePath = FileHelper.Relative(fi.FullName, dirPath); //求这个文件相对路径 fileItem.url = urlDom + fileItem.relativePath; fileItem.MD5 = MD5Helper.FileMD5(fi.FullName); //计算md5 //写到文件夹记录 folder.Add(fileItem); } var xml = XmlHelper.CreatXml(); folder.ToXml(xml.DocumentElement); //文件夹内容挂到xml文件的根节点 FileInfo xmlFileInfo = new FileInfo(xmlPath); //要保存的目录 if (!xmlFileInfo.Directory.Exists) { Directory.CreateDirectory(xmlFileInfo.Directory.FullName); } if (xmlFileInfo.Extension == ".zip")//如果是zip那就保存zip文件 { MemoryStream ms = new MemoryStream(); xml.Save(ms); using (ZipFile zip = new ZipFile(Encoding.Default)) { ZipEntry zipEntry = new ZipEntry(); zip.AddEntry(xmlFileInfo.Name.Replace(".zip", ".xml"), ms.ToArray());//把xml的内存流写到zip文件 zip.Save(xmlFileInfo.FullName); } } else { xml.Save(xmlFileInfo.FullName);//保存.xml文件 } }
private async void StartDownLoad() { Log.Debug("UpdateTask.StartDownLoad():当前执行线程id=" + Thread.CurrentThread.ManagedThreadId); int isDone = 0; Interlocked.Exchange(ref isDone, 0); Exception lastException = null; //下载ConfigXML(异步的) Http.Get(setting.xmlUrl).OnSuccess((WebHeaderCollection collection, Stream stream) => { try { var xml = XmlHelper.CreatXml(); if (setting.xmlUrl.EndsWith(".zip")) { MemoryStream ms = new MemoryStream(); CopyStream(stream, ms); MemoryStream xmlms = new MemoryStream(); ms.Position = 0; ZipFile zip = ZipFile.Read(ms); ZipEntry ze = zip.Entries.First();//第一个实体 ze.Extract(xmlms); xmlms.Position = 0; xml.Load(xmlms); //从下载文件流中读xml } else { xml.Load(stream); //从下载文件流中读xml } Log.Info("UpdateTask.StartDownLoad():下载xml成功!"); originFolder = new OriginFolder(); var node = xml.DocumentElement.SelectSingleNode("./" + typeof(OriginFolder).Name); originFolder.FromXml(node);//从xml文件根节点反序列化 //使用服务器上下载下来的来初始化客户端的 localFolder.InitWithFolderConfig(originFolder.fileItemDict); //检查本地哪些文件需要下载 localFolder.CheekNeedDownload(); Interlocked.Increment(ref isDone);//标记为1,下载xml完成 } catch (Exception e) { Log.Error($"UpdateTask.StartDownLoad():下载xml异常,{setting.xmlUrl} - " + e.Message); lastException = e; //记录异常信息 Interlocked.Decrement(ref isDone); //也标记它非零了, -1 } }).OnFail((e) => { Log.Warning($"UpdateTask.StartDownLoad():OnFail()下载xml失败,{setting.xmlUrl} - " + e.Message); lastException = e; //记录异常信息 Interlocked.Decrement(ref isDone); //也标记它非零了, -1 }).Go(); //一直卡在这里等待上面的方法执行完成 while (true) { Log.Debug("UpdateTask.StartDownLoad():await Task.Delay(1)之前 当前执行线程id=" + Thread.CurrentThread.ManagedThreadId); await Task.Delay(1); //await WaitDelay();//这里使用Task.Delay和这个函数都会导致线程改变 Log.Debug("UpdateTask.StartDownLoad():await Task.Delay(1)之后 当前执行线程id=" + Thread.CurrentThread.ManagedThreadId); if (isDone > 0) { break; } if (isDone < 0) { try { EventError?.Invoke(lastException); } catch (Exception ex) { Log.Warning("UpdateTask.StartDownLoad():执行用户事件EventError异常:" + ex.Message); } return;//这里下载xml失败了,那这个函数不需要往下走了 } } int errorCount = 0; while (errorCount < 5)//只重试5次 { //遍历每一项下载 foreach (var kvp in localFolder.fileItemClientDict) { await DownLoadOneFile(kvp.Value); } if (CheckTempFileCorrect())//如果确定已经下载ok了 { break; } errorCount++; } //重试超过五次是下载失败 if (errorCount >= 5) { Log.Warning($"UpdateTask.StartDownLoad():下载文件失败,重试超过5次!"); try { EventError?.Invoke(new Exception(setting.xmlUrl)); } catch (Exception ex) { Log.Warning("UpdateTask.StartDownLoad():执行用户事件EventError异常:" + ex.Message); } return; } //执行下载完成事件 if (EventDownloadSuccess != null) { try { EventDownloadSuccess(this); } catch (Exception e) { Log.Error("UpdateTask.StartProc():执行用户事件EventDownloadSuccess异常:" + e.Message); } } }