From f625fd51a0fa33c87feeb6890390a6b253ef38a1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 6 Dec 2016 00:37:12 -0500 Subject: always clean up files during install (#188) --- .../InteractiveInstaller.cs | 156 ++++++++++----------- 1 file changed, 77 insertions(+), 79 deletions(-) (limited to 'src/StardewModdingAPI.Installer') diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index 1d3802ab..7b082893 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -131,90 +131,88 @@ namespace StardewModdingApi.Installer Console.WriteLine(); /**** - ** Perform action + ** Always uninstall old files ****/ - switch (action) + // restore game launcher + if (platform == Platform.Mono && File.Exists(paths.unixLauncherBackup)) { - case ScriptAction.Uninstall: - { - // restore game launcher - if (platform == Platform.Mono && File.Exists(paths.unixLauncherBackup)) - { - this.PrintDebug("Restoring game launcher..."); - if (File.Exists(paths.unixLauncher)) - File.Delete(paths.unixLauncher); - File.Move(paths.unixLauncherBackup, paths.unixLauncher); - } - - // remove SMAPI files - this.PrintDebug("Removing SMAPI files..."); - foreach (string filename in this.UninstallFiles) - { - string targetPath = Path.Combine(installDir.FullName, filename); - if (File.Exists(targetPath)) - File.Delete(targetPath); - } - } - break; + this.PrintDebug("Removing SMAPI launcher..."); + if (File.Exists(paths.unixLauncher)) + File.Delete(paths.unixLauncher); + File.Move(paths.unixLauncherBackup, paths.unixLauncher); + } + + // remove old files + string[] removeFiles = this.UninstallFiles + .Select(path => Path.Combine(installDir.FullName, path)) + .Where(File.Exists) + .ToArray(); + if (removeFiles.Any()) + { + this.PrintDebug(action == ScriptAction.Install ? "Removing previous SMAPI files..." : "Removing SMAPI files..."); + foreach (string path in removeFiles) + File.Delete(path); + } + + /**** + ** Install new files + ****/ + if (action == ScriptAction.Install) + { + // copy SMAPI files to game dir + this.PrintDebug("Adding SMAPI files..."); + foreach (FileInfo sourceFile in packageDir.EnumerateFiles()) + { + string targetPath = Path.Combine(installDir.FullName, sourceFile.Name); + if (File.Exists(targetPath)) + File.Delete(targetPath); + sourceFile.CopyTo(targetPath); + } - case ScriptAction.Install: + // replace mod launcher (if possible) + if (platform == Platform.Mono) + { + this.PrintDebug("Safely replacing game launcher..."); + if (!File.Exists(paths.unixLauncherBackup)) + File.Move(paths.unixLauncher, paths.unixLauncherBackup); + else if (File.Exists(paths.unixLauncher)) + File.Delete(paths.unixLauncher); + + File.Move(paths.unixSmapiLauncher, paths.unixLauncher); + } + + // create mods directory (if needed) + DirectoryInfo modsDir = new DirectoryInfo(Path.Combine(installDir.FullName, "Mods")); + if (!modsDir.Exists) + { + this.PrintDebug("Creating mods directory..."); + modsDir.Create(); + } + + // add or replace bundled mods + Directory.CreateDirectory(Path.Combine(installDir.FullName, "Mods")); + DirectoryInfo packagedModsDir = new DirectoryInfo(Path.Combine(packageDir.FullName, "Mods")); + if (packagedModsDir.Exists && packagedModsDir.EnumerateDirectories().Any()) + { + this.PrintDebug("Adding bundled mods..."); + foreach (DirectoryInfo sourceDir in packagedModsDir.EnumerateDirectories()) { - // copy SMAPI files to game dir - this.PrintDebug("Copying SMAPI files to game directory..."); - foreach (FileInfo sourceFile in packageDir.EnumerateFiles()) - { - string targetPath = Path.Combine(installDir.FullName, sourceFile.Name); - if (File.Exists(targetPath)) - File.Delete(targetPath); - sourceFile.CopyTo(targetPath); - } - - // replace mod launcher (if possible) - if (platform == Platform.Mono) - { - this.PrintDebug("Safely replacing game launcher..."); - if (!File.Exists(paths.unixLauncherBackup)) - File.Move(paths.unixLauncher, paths.unixLauncherBackup); - else if (File.Exists(paths.unixLauncher)) - File.Delete(paths.unixLauncher); - - File.Move(paths.unixSmapiLauncher, paths.unixLauncher); - } - - // create mods directory (if needed) - DirectoryInfo modsDir = new DirectoryInfo(Path.Combine(installDir.FullName, "Mods")); - if (!modsDir.Exists) - { - this.PrintDebug("Creating mods directory..."); - modsDir.Create(); - } - - // add or replace bundled mods - Directory.CreateDirectory(Path.Combine(installDir.FullName, "Mods")); - DirectoryInfo packagedModsDir = new DirectoryInfo(Path.Combine(packageDir.FullName, "Mods")); - if (packagedModsDir.Exists && packagedModsDir.EnumerateDirectories().Any()) - { - this.PrintDebug("Adding bundled mods..."); - foreach (DirectoryInfo sourceDir in packagedModsDir.EnumerateDirectories()) - { - this.PrintDebug($" adding {sourceDir.Name}..."); - - // initialise target dir - DirectoryInfo targetDir = new DirectoryInfo(Path.Combine(modsDir.FullName, sourceDir.Name)); - if (targetDir.Exists) - targetDir.Delete(recursive: true); - targetDir.Create(); - - // copy files - foreach (FileInfo sourceFile in sourceDir.EnumerateFiles()) - sourceFile.CopyTo(Path.Combine(targetDir.FullName, sourceFile.Name)); - } - } - - // remove obsolete appdata mods - this.InteractivelyRemoveAppDataMods(platform, modsDir); + this.PrintDebug($" adding {sourceDir.Name}..."); + + // initialise target dir + DirectoryInfo targetDir = new DirectoryInfo(Path.Combine(modsDir.FullName, sourceDir.Name)); + if (targetDir.Exists) + targetDir.Delete(recursive: true); + targetDir.Create(); + + // copy files + foreach (FileInfo sourceFile in sourceDir.EnumerateFiles()) + sourceFile.CopyTo(Path.Combine(targetDir.FullName, sourceFile.Name)); } - break; + } + + // remove obsolete appdata mods + this.InteractivelyRemoveAppDataMods(platform, modsDir); } Console.WriteLine(); -- cgit From 8304227cea5b971f17f0dbe980bc3edc76fb5e61 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 6 Dec 2016 00:41:12 -0500 Subject: remove obsolete mods/.cache directory on install (#187, #188) --- .../InteractiveInstaller.cs | 41 +++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'src/StardewModdingAPI.Installer') diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index 7b082893..c3b9a2e3 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -27,8 +27,8 @@ namespace StardewModdingApi.Installer @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley" }; - /// The files to remove when uninstalling SMAPI. - private readonly string[] UninstallFiles = + /// The directory or file paths to remove when uninstalling SMAPI, relative to the game directory. + private readonly string[] UninstallPaths = { // common "StardewModdingAPI.exe", @@ -45,7 +45,10 @@ namespace StardewModdingApi.Installer "System.Numerics.dll", // Windows only - "StardewModdingAPI.pdb" + "StardewModdingAPI.pdb", + + // obsolete + "Mods/.cache" }; @@ -59,16 +62,17 @@ namespace StardewModdingApi.Installer /// 1. Collect information (mainly OS and install path) and validate it. /// 2. Ask the user whether to install or uninstall. /// - /// Install flow: - /// 1. Copy the SMAPI files from package/Windows or package/Mono into the game directory. - /// 2. On Linux/Mac: back up the game launcher and replace it with the SMAPI launcher. (This isn't possible on Windows, so the user needs to configure it manually.) - /// 3. Create the 'Mods' directory. - /// 4. Copy the bundled mods into the 'Mods' directory (deleting any existing versions). - /// 5. Move any mods from app data into game's mods directory. - /// /// Uninstall logic: /// 1. On Linux/Mac: if a backup of the launcher exists, delete the launcher and restore the backup. - /// 2. Delete all files in the game directory matching one of the . + /// 2. Delete all files and folders in the game directory matching one of the . + /// + /// Install flow: + /// 1. Run the uninstall flow. + /// 2. Copy the SMAPI files from package/Windows or package/Mono into the game directory. + /// 3. On Linux/Mac: back up the game launcher and replace it with the SMAPI launcher. (This isn't possible on Windows, so the user needs to configure it manually.) + /// 4. Create the 'Mods' directory. + /// 5. Copy the bundled mods into the 'Mods' directory (deleting any existing versions). + /// 6. Move any mods from app data into game's mods directory. /// public void Run(string[] args) { @@ -143,15 +147,20 @@ namespace StardewModdingApi.Installer } // remove old files - string[] removeFiles = this.UninstallFiles + string[] removePaths = this.UninstallPaths .Select(path => Path.Combine(installDir.FullName, path)) - .Where(File.Exists) + .Where(path => Directory.Exists(path) || File.Exists(path)) .ToArray(); - if (removeFiles.Any()) + if (removePaths.Any()) { this.PrintDebug(action == ScriptAction.Install ? "Removing previous SMAPI files..." : "Removing SMAPI files..."); - foreach (string path in removeFiles) - File.Delete(path); + foreach (string path in removePaths) + { + if (Directory.Exists(path)) + Directory.Delete(path, recursive: true); + else + File.Delete(path); + } } /**** -- cgit From f0433e5a41c01d73edcd20a6767b7979f636c0e6 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 6 Dec 2016 22:19:38 -0500 Subject: tweak installer wording to avoid confusion --- release-notes.md | 3 ++- src/StardewModdingAPI.Installer/InteractiveInstaller.cs | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/StardewModdingAPI.Installer') diff --git a/release-notes.md b/release-notes.md index 3b16dcd6..20bb74ba 100644 --- a/release-notes.md +++ b/release-notes.md @@ -6,9 +6,10 @@ See [log](https://github.com/CLxS/SMAPI/compare/stable...develop). For players: * Installing SMAPI will now automatically clean up old SMAPI files. * Each mod now has its own `.cache` folder, so removing the mod won't leave orphaned cache files behind. + * Tweaked installer wording to avoid confusion. For developers: - * Fixed issue where you could no longer debug into an assembly because it was copied into the `.cache` directory. That will now only happen if necessary. + * Fixed an issue where you couldn't debug into an assembly because it was copied into the `.cache` directory. That will now only happen if necessary. ## 1.3 See [log](https://github.com/CLxS/SMAPI/compare/1.2...1.3). diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index c3b9a2e3..d7bf7b0e 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -119,7 +119,7 @@ namespace StardewModdingApi.Installer ScriptAction action; { - string choice = this.InteractivelyChoose("What do you want to do?", "1", "2"); + string choice = this.InteractivelyChoose("What do you want to do? Type 1 or 2, then press enter.", "1", "2"); switch (choice) { case "1": @@ -320,12 +320,11 @@ namespace StardewModdingApi.Installer } // ask user - Console.WriteLine("Oops, couldn't find your Stardew Valley install path automatically. You'll need to specify where the game is installed (or install SMAPI manually)."); + Console.WriteLine("Oops, couldn't find the game automatically."); while (true) { // get path from user - Console.WriteLine(" Enter the game's full directory path (the one containing 'StardewValley.exe' or 'Stardew Valley.exe')."); - Console.Write(" > "); + Console.WriteLine($"Type the file path to the game directory (the one containing '{(platform == Platform.Mono ? "StardewValley.exe" : "Stardew Valley.exe")}'), then press enter."); string path = Console.ReadLine()?.Trim(); if (string.IsNullOrWhiteSpace(path)) { -- cgit From 860ccb90f790807c0f551e10dfff3ae03279d965 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 7 Dec 2016 22:17:38 -0500 Subject: fix the installer not removing TrainerMod from appdata if it's already in the game mods folder --- release-notes.md | 1 + src/StardewModdingAPI.Installer/InteractiveInstaller.cs | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/StardewModdingAPI.Installer') diff --git a/release-notes.md b/release-notes.md index e92ccf35..133ae929 100644 --- a/release-notes.md +++ b/release-notes.md @@ -7,6 +7,7 @@ For players: * Installing SMAPI will now automatically clean up old SMAPI files. * Each mod now has its own `.cache` folder, so removing the mod won't leave orphaned cache files behind. * Tweaked installer wording to avoid confusion. + * Fixed the installer not removing TrainerMod from the legacy appdata mods directory if it's already present in the game mods directory. For developers: * Added a searchable `list_items` command to replace the `out_items`, `out_melee`, and `out_rings` commands. diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index d7bf7b0e..cfd64458 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -89,7 +89,6 @@ namespace StardewModdingApi.Installer unixLauncher = Path.Combine(installDir.FullName, "StardewValley"), unixLauncherBackup = Path.Combine(installDir.FullName, "StardewValley-original") }; - this.PrintDebug($"Detected {(platform == Platform.Windows ? "Windows" : "Linux or Mac")} with game in {installDir}."); /**** @@ -221,7 +220,7 @@ namespace StardewModdingApi.Installer } // remove obsolete appdata mods - this.InteractivelyRemoveAppDataMods(platform, modsDir); + this.InteractivelyRemoveAppDataMods(platform, modsDir, packagedModsDir); } Console.WriteLine(); @@ -362,8 +361,12 @@ namespace StardewModdingApi.Installer /// Interactively move mods out of the appdata directory. /// The current platform. /// The directory which should contain all mods. - private void InteractivelyRemoveAppDataMods(Platform platform, DirectoryInfo properModsDir) + /// The installer directory containing packaged mods. + private void InteractivelyRemoveAppDataMods(Platform platform, DirectoryInfo properModsDir, DirectoryInfo packagedModsDir) { + // get packaged mods to delete + string[] packagedModNames = packagedModsDir.GetDirectories().Select(p => p.Name).ToArray(); + // get path string homePath = platform == Platform.Windows ? Environment.GetEnvironmentVariable("APPDATA") @@ -385,6 +388,14 @@ namespace StardewModdingApi.Installer if (!isDir && !(entry is FileInfo)) continue; // should never happen + // delete packaged mods (newer version bundled into SMAPI) + if (isDir && packagedModNames.Contains(entry.Name, StringComparer.InvariantCultureIgnoreCase)) + { + this.PrintDebug($" Deleting {entry.Name} because it's bundled into SMAPI..."); + entry.Delete(); + continue; + } + // check paths string newPath = Path.Combine(properModsDir.FullName, entry.Name); if (isDir ? Directory.Exists(newPath) : File.Exists(newPath)) -- cgit From ae44f17205961116baef018bae0b8fe9196b27f0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 7 Dec 2016 22:43:05 -0500 Subject: fix installer not moving mods out of appdata if the game isn't installed on the same Windows partition (#184) --- release-notes.md | 3 +- .../InteractiveInstaller.cs | 32 +++++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'src/StardewModdingAPI.Installer') diff --git a/release-notes.md b/release-notes.md index 133ae929..e7712011 100644 --- a/release-notes.md +++ b/release-notes.md @@ -7,7 +7,8 @@ For players: * Installing SMAPI will now automatically clean up old SMAPI files. * Each mod now has its own `.cache` folder, so removing the mod won't leave orphaned cache files behind. * Tweaked installer wording to avoid confusion. - * Fixed the installer not removing TrainerMod from the legacy appdata mods directory if it's already present in the game mods directory. + * Fixed the installer not removing TrainerMod from appdata if it's already in the game mods directory. + * Fixed the installer not moving mods out of appdata if the game isn't installed on the same Windows partition. For developers: * Added a searchable `list_items` command to replace the `out_items`, `out_melee`, and `out_rings` commands. diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index cfd64458..ffdef37b 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -406,10 +406,7 @@ namespace StardewModdingApi.Installer // move into mods this.PrintDebug($" Moving {entry.Name} into the game's mod directory..."); - if (isDir) - (entry as DirectoryInfo).MoveTo(newPath); - else - (entry as FileInfo).MoveTo(newPath); + this.Move(entry, newPath); } // delete if empty @@ -421,5 +418,32 @@ namespace StardewModdingApi.Installer modDir.Delete(); } } + + /// Move a filesystem entry to a new parent directory. + /// The filesystem entry to move. + /// The destination path. + /// We can't use or , because those don't work across partitions. + private void Move(FileSystemInfo entry, string newPath) + { + // file + if (entry is FileInfo) + { + FileInfo file = (FileInfo)entry; + file.CopyTo(newPath); + file.Delete(); + } + + // directory + else + { + Directory.CreateDirectory(newPath); + + DirectoryInfo directory = (DirectoryInfo)entry; + foreach (FileSystemInfo child in directory.EnumerateFileSystemInfos()) + this.Move(child, Path.Combine(newPath, child.Name)); + + directory.Delete(); + } + } } } -- cgit From 47d5aef404e0a5c27d49b37faff9bd32ced6f3ff Mon Sep 17 00:00:00 2001 From: Patrick Müssig Date: Tue, 6 Dec 2016 23:02:37 +0100 Subject: SMAPI installer is able to read SDV install path from registry key --- .../InteractiveInstaller.cs | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/StardewModdingAPI.Installer') diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index ffdef37b..49014352 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Reflection; +using Microsoft.Win32; using StardewModdingApi.Installer.Enums; namespace StardewModdingApi.Installer @@ -318,6 +319,41 @@ namespace StardewModdingApi.Installer return new DirectoryInfo(defaultPath); } + if (platform == Platform.Windows) + { + // Needed to get 64Keys + RegistryKey localKey = Environment.Is64BitOperatingSystem ? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) : Registry.LocalMachine; + + string stardewValleyPath; + var registry = localKey.OpenSubKey(@"SOFTWARE\WOW6432Node\GOG.com\Games\1453375253"); + if (registry != null) + { + stardewValleyPath = (string)registry.GetValue("PATH"); + if (!string.IsNullOrEmpty(stardewValleyPath)) + { + registry.Close(); + if (Directory.Exists(stardewValleyPath)) + { + return new DirectoryInfo(stardewValleyPath); + } + } + } + + registry = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150"); + if (registry != null) + { + stardewValleyPath = (string)registry.GetValue("InstallLocation"); + if (!string.IsNullOrEmpty(stardewValleyPath)) + { + registry.Close(); + if (Directory.Exists(stardewValleyPath)) + { + return new DirectoryInfo(stardewValleyPath); + } + } + } + } + // ask user Console.WriteLine("Oops, couldn't find the game automatically."); while (true) -- cgit From 7af722ec1f0157ab9e894ef565ff3b8a9b4df938 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 7 Dec 2016 23:38:22 -0500 Subject: rename .targets file to better reflect contents, add to installer project --- .../StardewModdingAPI.AssemblyRewriters.csproj | 10 +--- .../StardewModdingAPI.Installer.csproj | 1 + src/StardewModdingAPI.sln | 2 +- src/StardewModdingAPI/StardewModdingAPI.csproj | 2 +- src/crossplatform.targets | 62 ++++++++++++++++++++++ src/dependencies.targets | 62 ---------------------- 6 files changed, 66 insertions(+), 73 deletions(-) create mode 100644 src/crossplatform.targets delete mode 100644 src/dependencies.targets (limited to 'src/StardewModdingAPI.Installer') diff --git a/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj b/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj index 51a49da0..1e6caacc 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj +++ b/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj @@ -47,7 +47,6 @@ prompt MinimumRecommendedRules.ruleset - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll @@ -82,13 +81,6 @@ - + - \ No newline at end of file diff --git a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj index 0a33cd57..9baa0d14 100644 --- a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj +++ b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj @@ -50,6 +50,7 @@ Always + diff --git a/src/StardewModdingAPI.sln b/src/StardewModdingAPI.sln index 37c08950..6e13b16b 100644 --- a/src/StardewModdingAPI.sln +++ b/src/StardewModdingAPI.sln @@ -11,7 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "metadata", "metadata", "{86 ProjectSection(SolutionItems) = preProject ..\.gitattributes = ..\.gitattributes ..\.gitignore = ..\.gitignore - dependencies.targets = dependencies.targets + crossplatform.targets = crossplatform.targets GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs ..\LICENSE = ..\LICENSE ..\README.md = ..\README.md diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj index 8a827ace..a90a0686 100644 --- a/src/StardewModdingAPI/StardewModdingAPI.csproj +++ b/src/StardewModdingAPI/StardewModdingAPI.csproj @@ -79,7 +79,6 @@ icon.ico - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll @@ -223,6 +222,7 @@ StardewModdingAPI.AssemblyRewriters + diff --git a/src/crossplatform.targets b/src/crossplatform.targets new file mode 100644 index 00000000..d5428967 --- /dev/null +++ b/src/crossplatform.targets @@ -0,0 +1,62 @@ + + + + $(HOME)/GOG Games/Stardew Valley/game + $(HOME)/.local/share/Steam/steamapps/common/Stardew Valley + + $(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS + + C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley + C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley + + + + + $(DefineConstants);SMAPI_FOR_WINDOWS + + + + False + + + False + + + False + + + False + + + $(GamePath)\Stardew Valley.exe + False + + + $(GamePath)\xTile.dll + False + False + + + + + + $(DefineConstants);SMAPI_FOR_UNIX + + + + $(GamePath)\MonoGame.Framework.dll + False + False + + + $(GamePath)\StardewValley.exe + False + + + $(GamePath)\xTile.dll + False + + + + + \ No newline at end of file diff --git a/src/dependencies.targets b/src/dependencies.targets deleted file mode 100644 index d5428967..00000000 --- a/src/dependencies.targets +++ /dev/null @@ -1,62 +0,0 @@ - - - - $(HOME)/GOG Games/Stardew Valley/game - $(HOME)/.local/share/Steam/steamapps/common/Stardew Valley - - $(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS - - C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley - C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley - - - - - $(DefineConstants);SMAPI_FOR_WINDOWS - - - - False - - - False - - - False - - - False - - - $(GamePath)\Stardew Valley.exe - False - - - $(GamePath)\xTile.dll - False - False - - - - - - $(DefineConstants);SMAPI_FOR_UNIX - - - - $(GamePath)\MonoGame.Framework.dll - False - False - - - $(GamePath)\StardewValley.exe - False - - - $(GamePath)\xTile.dll - False - - - - - \ No newline at end of file -- cgit From 7e76d90c5567fbc1d4ebeb8e3fc25095d4af4ce9 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 7 Dec 2016 23:52:56 -0500 Subject: refactor registry checks for crossplatform compatibility (#189) --- .../InteractiveInstaller.cs | 92 +++++++++++----------- 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'src/StardewModdingAPI.Installer') diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs index 49014352..9c8f8af9 100644 --- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs +++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +#if SMAPI_FOR_WINDOWS using Microsoft.Win32; +#endif using StardewModdingApi.Installer.Enums; namespace StardewModdingApi.Installer @@ -15,18 +18,37 @@ namespace StardewModdingApi.Installer *********/ /// The default file paths where Stardew Valley can be installed. /// Derived from the crossplatform mod config: https://github.com/Pathoschild/Stardew.ModBuildConfig. - private readonly string[] DefaultInstallPaths = { - // Linux - $"{Environment.GetEnvironmentVariable("HOME")}/GOG Games/Stardew Valley/game", - $"{Environment.GetEnvironmentVariable("HOME")}/.local/share/Steam/steamapps/common/Stardew Valley", + private IEnumerable DefaultInstallPaths + { + get + { + // Linux + yield return $"{Environment.GetEnvironmentVariable("HOME")}/GOG Games/Stardew Valley/game"; + yield return $"{Environment.GetEnvironmentVariable("HOME")}/.local/share/Steam/steamapps/common/Stardew Valley"; - // Mac - $"{Environment.GetEnvironmentVariable("HOME")}/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS", + // Mac + yield return $"{Environment.GetEnvironmentVariable("HOME")}/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS"; - // Windows - @"C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley", - @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley" - }; + // Windows + yield return @"C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley"; + yield return @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley"; + + // Windows registry +#if SMAPI_FOR_WINDOWS + IDictionary registryKeys = new Dictionary + { + [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150"] = "InstallLocation", // Steam + [@"SOFTWARE\WOW6432Node\GOG.com\Games\1453375253"] = "PATH", // GOG on 64-bit Windows + }; + foreach (var pair in registryKeys) + { + string path = this.GetLocalMachineRegistryValue(pair.Key, pair.Value); + if (!string.IsNullOrWhiteSpace(path)) + yield return path; + } +#endif + } + } /// The directory or file paths to remove when uninstalling SMAPI, relative to the game directory. private readonly string[] UninstallPaths = @@ -262,6 +284,21 @@ namespace StardewModdingApi.Installer } } +#if SMAPI_FOR_WINDOWS + /// Get the value of a key in the Windows registry. + /// The full path of the registry key relative to HKLM. + /// The name of the value. + private string GetLocalMachineRegistryValue(string key, string name) + { + RegistryKey localMachine = Environment.Is64BitOperatingSystem ? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) : Registry.LocalMachine; + RegistryKey openKey = localMachine.OpenSubKey(key); + if (openKey == null) + return null; + using (openKey) + return (string)openKey.GetValue(name); + } +#endif + /// Print a debug message. /// The text to print. private void PrintDebug(string text) @@ -319,41 +356,6 @@ namespace StardewModdingApi.Installer return new DirectoryInfo(defaultPath); } - if (platform == Platform.Windows) - { - // Needed to get 64Keys - RegistryKey localKey = Environment.Is64BitOperatingSystem ? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) : Registry.LocalMachine; - - string stardewValleyPath; - var registry = localKey.OpenSubKey(@"SOFTWARE\WOW6432Node\GOG.com\Games\1453375253"); - if (registry != null) - { - stardewValleyPath = (string)registry.GetValue("PATH"); - if (!string.IsNullOrEmpty(stardewValleyPath)) - { - registry.Close(); - if (Directory.Exists(stardewValleyPath)) - { - return new DirectoryInfo(stardewValleyPath); - } - } - } - - registry = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150"); - if (registry != null) - { - stardewValleyPath = (string)registry.GetValue("InstallLocation"); - if (!string.IsNullOrEmpty(stardewValleyPath)) - { - registry.Close(); - if (Directory.Exists(stardewValleyPath)) - { - return new DirectoryInfo(stardewValleyPath); - } - } - } - } - // ask user Console.WriteLine("Oops, couldn't find the game automatically."); while (true) -- cgit