/// <summary> /// Locates the game /// </summary> /// <returns>Null if the game was not found. Otherwise a valid or empty path for the install directory</returns> public override async Task <FileSystemPath?> LocateAsync() { FileSystemPath installDir; try { // Get the key path var keyPath = RegistryHelpers.CombinePaths(CommonRegistryPaths.InstalledPrograms, $"Steam App {SteamID}"); using var key = RegistryHelpers.GetKeyFromFullPath(keyPath, RegistryView.Registry64); // Get the install directory if (!(key?.GetValue("InstallLocation") is string dir)) { RL.Logger?.LogInformationSource($"The {Game} was not found under Steam Apps"); await Services.MessageUI.DisplayMessageAsync(Resources.LocateGame_InvalidSteamGame, Resources.LocateGame_InvalidSteamGameHeader, MessageType.Error); return(null); } installDir = dir; } catch (Exception ex) { ex.HandleError("Getting Steam game install directory"); await Services.MessageUI.DisplayMessageAsync(Resources.LocateGame_InvalidSteamGame, Resources.LocateGame_InvalidSteamGameHeader, MessageType.Error); return(null); } // Make sure the game is valid if (!await IsValidAsync(installDir)) { RL.Logger?.LogInformationSource($"The {Game} install directory was not valid"); await Services.MessageUI.DisplayMessageAsync(Resources.LocateGame_InvalidSteamGame, Resources.LocateGame_InvalidSteamGameHeader, MessageType.Error); return(null); } return(installDir); }
/// <summary> /// Opens the specified registry key path in RegEdit /// </summary> /// <param name="registryKeyPath">The key path to open</param> /// <returns>The task</returns> public async Task OpenRegistryKeyAsync(string registryKeyPath) { if (!RegistryHelpers.KeyExists(registryKeyPath)) { await Services.MessageUI.DisplayMessageAsync(Resources.File_RegKeyNotFound, Resources.File_RegKeyNotFoundHeader, MessageType.Error); return; } try { WindowsHelpers.OpenRegistryPath(registryKeyPath); RL.Logger?.LogDebugSource($"The Registry key path {registryKeyPath} was opened"); } catch (Exception ex) { ex.HandleError("Opening Registry key path", registryKeyPath); await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.File_OpenRegKeyError, Resources.File_OpenRegKeyErrorHeader); } }
/// <summary> /// Enumerates the programs from the Registry uninstall key /// </summary> /// <returns>The programs</returns> protected virtual IEnumerable <InstalledProgram> EnumerateRegistryUninstallPrograms() { RL.Logger?.LogInformationSource("Getting installed programs from the Registry"); // Get 64-bit location if on 64-bit system var keys = Environment.Is64BitOperatingSystem ? new RegistryKey[] { RegistryHelpers.GetKeyFromFullPath(CommonRegistryPaths.InstalledPrograms, RegistryView.Registry32), RegistryHelpers.GetKeyFromFullPath(CommonRegistryPaths.InstalledPrograms, RegistryView.Registry64) } : new RegistryKey[] { RegistryHelpers.GetKeyFromFullPath(CommonRegistryPaths.InstalledPrograms, RegistryView.Registry32), }; // Enumerate the uninstall keys foreach (var key in keys) { // Dispose key when done using RegistryKey registryKey = key; // Enumerate the sub keys foreach (string subKeyName in registryKey.GetSubKeyNames()) { // Make sure it's not a Windows update if (subKeyName.StartsWith("KB") && subKeyName.Length == 8) { continue; } // Open the sub key using RegistryKey subKey = registryKey.OpenSubKey(subKeyName); // Make sure the key is not null if (subKey == null) { continue; } // Make sure it is not a system component if (subKey.GetValue("SystemComponent") as int? == 1) { continue; } if (subKey.GetValue("WindowsInstaller") as int? == 1) { continue; } // Make sure it has an uninstall string if (!subKey.HasValue("UninstallString")) { continue; } if (subKey.HasValue("ParentKeyName")) { continue; } // Make sure it has a display name if (!(subKey.GetValue("DisplayName") is string dn)) { continue; } // Make sure it has an install location if (!(subKey.GetValue("InstallLocation") is string dir)) { continue; } yield return(new InstalledProgram(dn, subKey.Name, dir)); } } }
/// <summary> /// Runs the post-update code /// </summary> private async Task PostUpdateAsync() { if (Data.LastVersion < new Version(4, 0, 0, 6)) { Data.EnableAnimations = true; } if (Data.LastVersion < new Version(4, 1, 1, 0)) { Data.ShowIncompleteTranslations = false; } if (Data.LastVersion < new Version(4, 5, 0, 0)) { Data.LinkItemStyle = LinkItemStyles.List; Data.ApplicationPath = Assembly.GetEntryAssembly()?.Location; Data.ForceUpdate = false; Data.GetBetaUpdates = false; } if (Data.LastVersion < new Version(4, 6, 0, 0)) { Data.LinkListHorizontalAlignment = HorizontalAlignment.Left; } if (Data.LastVersion < new Version(5, 0, 0, 0)) { Data.CompressBackups = true; Data.FiestaRunVersion = FiestaRunEdition.Default; // Due to the fiesta run version system being changed the game has to be removed and then re-added Data.Games.Remove(Games.RaymanFiestaRun); // If a Fiesta Run backup exists the name needs to change to the new standard var fiestaBackupDir = Data.BackupLocation + AppViewModel.BackupFamily + "Rayman Fiesta Run"; if (fiestaBackupDir.DirectoryExists) { try { // Read the app data file JObject appData = new StringReader(File.ReadAllText(CommonPaths.AppUserDataPath)).RunAndDispose(x => new JsonTextReader(x).RunAndDispose(y => JsonSerializer.Create().Deserialize(y))).CastTo <JObject>(); // Get the previous Fiesta Run version var isWin10 = appData["IsFiestaRunWin10Edition"].Value <bool>(); // Set the current edition Data.FiestaRunVersion = isWin10 ? FiestaRunEdition.Win10 : FiestaRunEdition.Default; RCPServices.File.MoveDirectory(fiestaBackupDir, Data.BackupLocation + AppViewModel.BackupFamily + Games.RaymanFiestaRun.GetGameInfo().BackupName, true, true); } catch (Exception ex) { ExceptionExtensions.HandleError(ex, "Moving Fiesta Run backups to 5.0.0 standard"); await Services.MessageUI.DisplayMessageAsync(Metro.Resources.PostUpdate_MigrateFiestaRunBackup5Error, Metro.Resources.PostUpdate_MigrateBackupErrorHeader, MessageType.Error); } } // Remove old temp dir try { RCPServices.File.DeleteDirectory(Path.Combine(Path.GetTempPath(), "RCP_Metro")); } catch (Exception ex) { ExceptionExtensions.HandleError(ex, "Cleaning pre-5.0.0 temp"); } Data.DisableDowngradeWarning = false; } if (Data.LastVersion < new Version(6, 0, 0, 0)) { Data.EducationalDosBoxGames = null; Data.RRR2LaunchMode = RRR2LaunchMode.AllGames; Data.RabbidsGoHomeLaunchData = null; } if (Data.LastVersion < new Version(6, 0, 0, 2)) { // By default, add all games to the jump list collection Data.JumpListItemIDCollection = RCPServices.App.GetGames. Where(x => x.IsAdded()). Select(x => x.GetManager().GetJumpListItems().Select(y => y.ID)). SelectMany(x => x). ToList(); } if (Data.LastVersion < new Version(7, 0, 0, 0)) { Data.IsUpdateAvailable = false; if (Data.UserLevel == UserLevel.Normal) { Data.UserLevel = UserLevel.Advanced; } } if (Data.LastVersion < new Version(7, 1, 0, 0)) { Data.InstalledGames = new HashSet <Games>(); } if (Data.LastVersion < new Version(7, 1, 1, 0)) { Data.CategorizeGames = true; } if (Data.LastVersion < new Version(7, 2, 0, 0)) { Data.ShownRabbidsActivityCenterLaunchMessage = false; } if (Data.LastVersion < new Version(9, 0, 0, 0)) { const string regUninstallKeyName = "RCP_Metro"; // Since support has been removed for showing the program under installed programs we now have to remove the key var keyPath = RegistryHelpers.CombinePaths(CommonRegistryPaths.InstalledPrograms, regUninstallKeyName); // Check if the key exists if (RegistryHelpers.KeyExists(keyPath)) { // Make sure the user is running as admin if (RCPServices.App.IsRunningAsAdmin) { try { // Open the parent key using var parentKey = RegistryHelpers.GetKeyFromFullPath(CommonRegistryPaths.InstalledPrograms, RegistryView.Default, true); // Delete the sub-key parentKey.DeleteSubKey(regUninstallKeyName); RL.Logger?.LogInformationSource("The program Registry key has been deleted"); } catch (Exception ex) { ExceptionExtensions.HandleError(ex, "Removing uninstall Registry key"); await Services.MessageUI.DisplayMessageAsync($"The Registry key {keyPath} could not be removed", MessageType.Error); } } else { await Services.MessageUI.DisplayMessageAsync($"The Registry key {keyPath} could not be removed", MessageType.Error); } } if (Data.TPLSData != null) { Data.TPLSData.IsEnabled = false; await Services.MessageUI.DisplayMessageAsync(Metro.Resources.PostUpdate_TPLSUpdatePrompt); } } if (Data.LastVersion < new Version(9, 4, 0, 0)) { Data.Archive_GF_GenerateMipmaps = true; Data.Archive_GF_UpdateTransparency = Archive_GF_TransparencyMode.PreserveFormat; } if (Data.LastVersion < new Version(9, 5, 0, 0)) { Data.BinarySerializationFileLogPath = FileSystemPath.EmptyPath; } if (Data.LastVersion < new Version(10, 0, 0, 0)) { Data.SyncTheme = false; } // Re-deploy files await RCPServices.App.DeployFilesAsync(true); // Refresh the jump list RefreshJumpList(); // Close the splash screen CloseSplashScreen(); // Show app news new AppNewsDialog().ShowDialog(); }
/// <summary> /// Refreshes the link items /// </summary> /// <returns>The task</returns> public async Task RefreshAsync() { using (await AsyncLock.LockAsync()) { try { Stopwatch time = new Stopwatch(); time.Start(); RL.Logger?.LogInformationSource("The links are refreshing..."); LocalLinkItems.Clear(); // Config files LocalLinkItems.Add(new LinkItemViewModel[] { new LinkItemViewModel(CommonPaths.UbiIniPath1, Resources.Links_Local_PrimaryUbiIni), new LinkItemViewModel(CommonPaths.UbiIniPath2, Resources.Links_Local_SecondaryUbiIni, UserLevel.Advanced), new LinkItemViewModel(Games.Rayman2.IsAdded() ? Games.Rayman2.GetInstallDir() + "ubi.ini" : FileSystemPath.EmptyPath, Resources.Links_Local_R2UbiIni, UserLevel.Advanced), new LinkItemViewModel(Environment.SpecialFolder.CommonApplicationData.GetFolderPath() + @"Ubisoft\RGH Launcher\1.0.0.0\Launcher_5.exe.config", Resources.Links_Local_RGHConfig, UserLevel.Advanced) }); // DOSBox files LocalLinkItems.Add(new LinkItemViewModel[] { new LinkItemViewModel(new FileSystemPath(Data.DosBoxPath), Resources.Links_Local_DOSBox), new LinkItemViewModel(new FileSystemPath(Data.DosBoxConfig), Resources.Links_Local_DOSBoxConfig, UserLevel.Technical) }); // Steam paths try { using RegistryKey key = RegistryHelpers.GetKeyFromFullPath( @"HKEY_CURRENT_USER\Software\Valve\Steam", RegistryView.Default); if (key != null) { FileSystemPath steamDir = key.GetValue("SteamPath", null)?.ToString(); var steamExe = key.GetValue("SteamExe", null)?.ToString(); if (steamDir.DirectoryExists) { LocalLinkItems.Add(new LinkItemViewModel[] { new LinkItemViewModel(steamDir + steamExe, Resources.Links_Local_Steam), new LinkItemViewModel(steamDir + @"steamapps\common", Resources.Links_Local_SteamGames, UserLevel.Advanced) }); } } } catch (Exception ex) { ex.HandleUnexpected("Getting Steam Registry key"); } // GOG paths try { using RegistryKey key = RegistryHelpers.GetKeyFromFullPath( @"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\GOG.com\GalaxyClient\paths", RegistryView.Default); if (key != null) { FileSystemPath gogDir = key.GetValue("client", null)?.ToString(); if (gogDir.DirectoryExists) { LocalLinkItems.Add(new LinkItemViewModel[] { new LinkItemViewModel(gogDir + "GalaxyClient.exe", Resources.Links_Local_GOGClient), new LinkItemViewModel(gogDir + @"Games", Resources.Links_Local_GOGGames, UserLevel.Advanced) }); } } } catch (Exception ex) { ex.HandleUnexpected("Getting GOG Galaxy Registry key"); } // Registry paths LocalLinkItems.Add(new LinkItemViewModel[] { new LinkItemViewModel(CommonPaths.RaymanRavingRabbidsRegistryKey, Resources.Links_Local_RRRRegSettings, UserLevel.Technical), new LinkItemViewModel(CommonPaths.RaymanRavingRabbids2RegistryKey, Resources.Links_Local_RRR2RegSettings, UserLevel.Technical), new LinkItemViewModel(CommonPaths.RaymanOriginsRegistryKey, Resources.Links_Local_RORegSettings, UserLevel.Technical), new LinkItemViewModel(CommonPaths.RaymanLegendsRegistryKey, Resources.Links_Local_RLRegSettings, UserLevel.Technical), new LinkItemViewModel(@"HKEY_CURRENT_USER\Software\Zeus Software\nGlide", Resources.Links_Local_nGlideRegSettings, UserLevel.Technical), new LinkItemViewModel(@"HKEY_CURRENT_USER\Software\Zeus Software\nGlide2", Resources.Links_Local_nGlide2RegSettings, UserLevel.Technical) }); // Debug paths LocalLinkItems.Add(new LinkItemViewModel[] { new LinkItemViewModel(CommonPaths.UserDataBaseDir, Resources.Links_Local_AppData, UserLevel.Technical), new LinkItemViewModel(CommonPaths.LogFile, Resources.Links_Local_LogFile, UserLevel.Debug), new LinkItemViewModel(CommonPaths.UtilitiesBaseDir, Resources.Links_Local_Utilities, UserLevel.Debug), new LinkItemViewModel(CommonPaths.RegistryBaseKey, Resources.Links_Local_RegAppData, UserLevel.Technical) }); // Community links CommunityLinkItems.Clear(); CommunityLinkItems.AddRange(new LinkItemViewModel[][] { new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://raymanpc.com/"), Resources.Links_Community_RPC), new LinkItemViewModel(new Uri("https://raymanpc.com/wiki/en/Main_Page"), Resources.Links_Community_RayWiki), new LinkItemViewModel(new Uri("https://raytunes.raymanpc.com/"), Resources.Links_Community_RayTunes), new LinkItemViewModel(new Uri("https://raysaves.raymanpc.com/"), Resources.Links_Community_RaySaves) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://twitter.com/RaymanCentral"), Resources.Links_Community_RaymanCentral), new LinkItemViewModel(new Uri("https://twitter.com/RaymanTogether"), Resources.Links_Community_RaymanTogether), new LinkItemViewModel(new Uri("https://twitter.com/RaymanReanimate"), Resources.Links_Community_RaymanReanimated) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://raym.app/"), Resources.Links_Community_raym_app), new LinkItemViewModel(new Uri("https://raym.app/maps/"), Resources.Links_Community_Raymap), new LinkItemViewModel(new Uri("https://raym.app/menezis/"), Resources.Links_Community_Menezis_Browser) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("http://www.kmgassociates.com/rayman/index.html"), Resources.Links_Community_KMG), new LinkItemViewModel(new Uri("http://www.rayman-fanpage.de/"), Resources.Links_Community_Fanpage) } }); // Forum links ForumLinkItems.Clear(); ForumLinkItems.AddRange(new LinkItemViewModel[][] { new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://raymanpc.com/forum/index.php"), Resources.Links_Forums_RPC) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://forums.ubi.com/forumdisplay.php/47-Rayman"), Resources.Links_Forums_Ubisoft), new LinkItemViewModel(new Uri("https://www.gog.com/forum/rayman_series"), Resources.Links_Forums_GOG) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://steamcommunity.com/app/15060/discussions/"), Resources.Links_Forums_Steam_R2), new LinkItemViewModel(new Uri("https://steamcommunity.com/app/15080/discussions/"), Resources.Links_Forums_Steam_RRR), new LinkItemViewModel(new Uri("https://steamcommunity.com/app/207490/discussions/"), Resources.Links_Forums_Steam_RO), new LinkItemViewModel(new Uri("https://steamcommunity.com/app/242550/discussions/"), Resources.Links_Forums_Steam_RL) } }); // Tools links ToolsLinkItems.Clear(); ToolsLinkItems.AddRange(new LinkItemViewModel[][] { new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=5755"), Resources.Links_Tools_RDEditor), new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=25867"), Resources.Links_Tools_RayPlus) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=25013"), Resources.Links_Tools_RayTwol), new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=23423"), Resources.Links_Tools_R2Tools), new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=23420"), Resources.Links_Tools_R2Moonjump), new LinkItemViewModel( new Uri("https://github.com/rtsonneveld/Rayman2FunBox/releases"), Resources.Links_Tools_R2FunBox) }, new LinkItemViewModel[] { new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=12854"), Resources.Links_Tools_BetterR3), new LinkItemViewModel(new Uri("https://raymanpc.com/forum/viewtopic.php?t=25053"), Resources.Links_Tools_R3GCTexturePack) } }); time.Stop(); RL.Logger?.LogInformationSource("The links have refreshed"); RL.Logger?.LogDebugSource($"The link refresh time was {time.ElapsedMilliseconds} ms"); } catch (Exception ex) { ex.HandleError("Refreshing links"); } } }