public async Task RetrieveLocalXenkoVersions() { List <RecentProjectViewModel> currentRecentProjects; lock (RecentProjects) { currentRecentProjects = new List <RecentProjectViewModel>(RecentProjects); } try { var localPackages = await RunLockTask(() => store.GetPackagesInstalled(store.MainPackageIds).OrderByDescending(p => p.Version).ToList()); lock (objectLock) { // Retrieve all local packages var packages = localPackages.Where(p => !store.IsDevRedirectPackage(p)).GroupBy(p => $"{p.Version.Version.Major}.{p.Version.Version.Minor}", p => p); var updatedLocalPackages = new HashSet <XenkoStoreVersionViewModel>(); foreach (var package in packages) { var localPackage = package.FirstOrDefault(); if (localPackage != null) { // Find if we already have this package in our list int index = xenkoVersions.BinarySearch(Tuple.Create(localPackage.Version.Version.Major, localPackage.Version.Version.Minor)); XenkoStoreVersionViewModel version; if (index < 0) { // If not, add it version = new XenkoStoreVersionViewModel(this, store, localPackage, localPackage.Version.Version.Major, localPackage.Version.Version.Minor); Dispatcher.Invoke(() => xenkoVersions.Add(version)); } else { version = (XenkoStoreVersionViewModel)xenkoVersions[index]; } version.UpdateLocalPackage(localPackage); updatedLocalPackages.Add(version); } } // Update versions that are not installed locally anymore Dispatcher.Invoke(() => { foreach (var xenkoUninstalledVersion in xenkoVersions.OfType <XenkoStoreVersionViewModel>().Where(x => !updatedLocalPackages.Contains(x))) { xenkoUninstalledVersion.UpdateLocalPackage(null); } }); // Update the active version if it is now invalid. if (ActiveVersion == null || !xenkoVersions.Contains(ActiveVersion) || !ActiveVersion.CanDelete) { ActiveVersion = XenkoVersions.FirstOrDefault(x => x.CanDelete); } if (!lastActiveVersionRestored) { var restoredVersion = XenkoVersions.FirstOrDefault(x => x.CanDelete && x.Name == LauncherSettings.ActiveVersion); if (restoredVersion != null) { ActiveVersion = restoredVersion; lastActiveVersionRestored = true; } } } var devPackages = localPackages.Where(store.IsDevRedirectPackage); Dispatcher.Invoke(() => xenkoVersions.RemoveWhere(x => x is XenkoDevVersionViewModel)); foreach (var package in devPackages) { try { var realPath = File.ReadAllText(store.GetRedirectFile(package)); if (!Directory.Exists(realPath)) { throw new DirectoryNotFoundException(); } var version = new XenkoDevVersionViewModel(this, store, package, realPath, true); Dispatcher.Invoke(() => xenkoVersions.Add(version)); } catch (Exception e) { await ServiceProvider.Get <IDialogService>().MessageBox(string.Format(Strings.ErrorDevRedirect, e), MessageBoxButton.OK, MessageBoxImage.Information); } } } catch (Exception e) { // TODO: error e.Ignore(); } finally { Dispatcher.Invoke(() => { foreach (var project in currentRecentProjects) { // Manually discarding the possibility to upgrade from 1.0 if (project.XenkoVersionName == "1.0") { continue; } project.CompatibleVersions.Clear(); foreach (var version in XenkoVersions) { // We suppose all dev versions are compatible with any project. if (version is XenkoDevVersionViewModel) { project.CompatibleVersions.Add(version); } var storeVersion = version as XenkoStoreVersionViewModel; if (storeVersion != null && storeVersion.CanDelete) { // Discard the version that matches the recent project version if (project.XenkoVersion == new Version(storeVersion.Version.Version.Major, storeVersion.Version.Version.Minor)) { continue; } // Discard the versions that are anterior to the recent project version if (project.XenkoVersion > storeVersion.Version.Version) { continue; } project.CompatibleVersions.Add(version); } } } }); } }