/// <summary> /// Gets the packages referenced by the current package. /// </summary> /// <returns>IEnumerable<Package>.</returns> public IEnumerable <Package> GetPackagesFromCurrent() { if (CurrentPackage == null) { yield break; } yield return(CurrentPackage); foreach (var storeDep in CurrentPackage.Meta.Dependencies) { var package = Packages.Find(storeDep); // In case the package is not found (when working with session not fully loaded/resolved with all deps) if (package != null) { yield return(package); } } foreach (var localDep in CurrentPackage.LocalDependencies) { var package = Packages.Find(localDep.Id); // In case the package is not found (when working with session not fully loaded/resolved with all deps) if (package != null) { yield return(package); } } }
/// <summary> /// Renvoi le package associé au manifest en s'assurant qu'il soit à jour. /// </summary> /// <param name="packageName">Nom du package ou vide si strategyInterne</param> /// <returns></returns> public InternalPackage GetPackage(string packageName) { if (String.IsNullOrEmpty(packageName)) { if (_internalPackage == null) { _internalPackage = new InternalPackage(); } return(_internalPackage); } StrategyPackage package = Packages.Find(delegate(StrategyPackage p) { return(Utils.StringCompareEquals(p.Name, packageName)); }); if (package == null) { package = new StrategyPackage(packageName); Packages.Add(package); } if (package.Synchronize()) { return(package); } return(null); }
/// <summary> Test packages and symbols </summary> public void TestPackagesAndSymbols() { Packages packages = new Packages(); Package p = packages.global; // global package Symbol foo = p.Intern("foo"); Check(foo.name, "foo"); Check(foo.pkg, p); Check(foo.fullName, "foo"); Check(p.Intern("foo") == foo); // make sure interning returns the same instance Check(p.Unintern(foo.name)); // first one removes successfully Check(!p.Unintern(foo.name)); // but second time there is nothing to remove Check(p.Intern("foo") != foo); // since we uninterned, second interning will return a different one Package p2 = new Package("fancy"); // some fancy package Symbol foo2 = p2.Intern("foo"); Check(foo2.name, "foo"); Check(foo2.pkg, p2); Check(foo2.fullName, "fancy:foo"); // test the packages list Check(packages.global.name, (string)null); // get the global package Check(Val.Print(packages.global.Intern("foo")), "foo"); // check symbol name Check(packages.keywords.name, ""); // get the keywords package Check(Val.Print(packages.keywords.Intern("foo")), ":foo"); // check symbol name Check(packages.Find("fancy"), null); // make sure the fancy package was not added yet Check(packages.Add(p2), p2); // add our fancy custom package Check(packages.Intern("fancy"), p2); // get the fancy package - should be the same one Check(Val.Print(packages.Intern("fancy").Intern("foo")), "fancy:foo"); // check symbol name Check(packages.Remove(p2)); // check removal (should only return true the first time) Check(!packages.Remove(p2)); // check removal (should only return true the first time) }
/// <summary> 执行下载 </summary> bool DownloadPackages(DoWorkEventArgs e) { Directory.CreateDirectory(Context.UpdatePackagePath); Trace.TraceInformation("开始下载网络更新包"); var workerCount = Math.Max(1, Context.MultipleDownloadCount); var workers = new List <WebClient>(workerCount); var evt = new AutoResetEvent(false); var hasError = false; //Ping if (!string.IsNullOrEmpty(Context.UpdateMeta.UpdatePingUrl)) { try { Context.CreateWebClient().UploadData(new Uri(Context.UpdateMeta.UpdatePingUrl), new byte[0]); } catch (Exception) { } } //生成下载队列 Trace.TraceInformation("正在初始化 {0} 个WebClient", workerCount); for (var i = 0; i < workerCount; i++) { var client = Context.CreateWebClient(); client.DownloadFileCompleted += (s, e) => { var pkg = e.UserState as Package; var cnt = s as WebClient; pkg.LastError = e.Error; if (e.Error != null) { Trace.TraceWarning($"包【{pkg.Name}】下载失败:{e.Error.Message}"); OnPackageDownloadFailed(new PackageEventArgs(pkg)); } else if (pkg.IsLocalFileValid != true) { Trace.TraceWarning($"包【{pkg.Name}】MD5校验失败", "错误"); pkg.LastError = new Exception("不文件哈希值不正确或文件不存在"); OnPackageHashMismatch(new PackageEventArgs(pkg)); } if (pkg.LastError != null) { //如果出错,且重试次数在限制范围内,则重试 pkg.IncreaseFailureCounter(); if (pkg.RetryCount <= Context.MaxiumRetryDownloadCount) { Trace.TraceWarning($"包【{pkg.Name}】未能成功下载,正在进行第 {pkg.RetryCount} 次重试,最大重试次数为 {Context.MaxiumRetryDownloadCount}", "错误"); cnt.DownloadFileAsync(new Uri(pkg.SourceUri), pkg.LocalSavePath, pkg); OnPackageDownloadRetried(new PackageEventArgs(pkg)); return; } //标记出错 hasError = true; } //包下载完成事件 pkg.IsDownloading = false; pkg.IsDownloaded = pkg.LastError == null; OnPackageDownloadFinished(new PackageEventArgs(e.UserState as Package)); lock (Packages) { Trace.TraceInformation($"包【{pkg.Name}】下载操作完成:{(pkg.IsDownloaded ? "下载成功" : "下载失败")}"); evt.Set(); } }; client.DownloadProgressChanged += (s, e) => { var pkg = e.UserState as Package; pkg.DownloadedSize = e.BytesReceived; pkg.Size = e.TotalBytesToReceive > 0 ? e.TotalBytesToReceive : pkg.Size; OnDownloadProgressChanged(new PackageDownloadProgressChangedEventArgs(pkg, pkg.Size, pkg.DownloadedSize, e.ProgressPercentage)); }; workers.Add(client); } //开始处理事务 while (!hasError) { var breakFlag = false; lock (Packages) { //没有错误,则分配下个任务 WebClient client; while ((client = workers.Find(s => !s.IsBusy)) != null) { var nextPkg = Packages.Find(s => !s.IsDownloading && !s.IsDownloaded); if (nextPkg == null) { breakFlag = true; break; } nextPkg.IsDownloading = true; Trace.TraceInformation($"包【{nextPkg.Name}】开始下载"); OnPackageDownload(new PackageEventArgs(nextPkg)); Context.ResetWebClient(client); client.DownloadFileAsync(new Uri(Context.GetUpdatePackageFullUrl(nextPkg.Name)), nextPkg.LocalSavePath, nextPkg); } } if (breakFlag) { break; } evt.WaitOne(); Trace.TraceInformation("线程同步事件已收到"); } //不管任何原因中止下载,到这里时都需要等待所有客户端中止 while (true) { //出错了,那么对所有的客户端发出中止命令。这里不需要判断是否忙碌。 if (hasError) { Trace.TraceWarning("出现错误,正在取消所有包的下载队列"); workers.ForEach(s => s.CancelAsync()); } lock (Packages) { Trace.TraceInformation("等待下载队列完成操作"); if (workers.FindIndex(s => s.IsBusy) == -1) { break; } } evt.WaitOne(); } Trace.TraceInformation("完成下载网络更新包"); var errorPkgs = Packages.FindAll(m => m.LastError != null); if (errorPkgs.Count > 0) { throw new PackageDownloadException(errorPkgs.ToArray()); } return(!hasError); }