using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using StardewModdingAPI.Internal; namespace StardewModdingApi.Installer { /// The entry point for SMAPI's install and uninstall console app. internal class Program { /********* ** Properties *********/ /// The absolute path to search for referenced assemblies. [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute", Justification = "The assembly location is never null in this context.")] private static string DllSearchPath; /********* ** Public methods *********/ /// Run the install or uninstall script. /// The command line arguments. public static void Main(string[] args) { // set up assembly resolution string installerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); Program.DllSearchPath = Path.Combine(installerPath, "internal", EnvironmentUtility.DetectPlatform() == Platform.Windows ? "Windows" : "Mono", "smapi-internal"); AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve; // launch installer var installer = new InteractiveInstaller(); installer.Run(args); } /********* ** Private methods *********/ /// Method called when assembly resolution fails, which may return a manually resolved assembly. /// The event sender. /// The event arguments. private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e) { AssemblyName name = new AssemblyName(e.Name); foreach (FileInfo dll in new DirectoryInfo(Program.DllSearchPath).EnumerateFiles("*.dll")) { try { if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.InvariantCultureIgnoreCase)) return Assembly.LoadFrom(dll.FullName); } catch (Exception ex) { throw new InvalidOperationException($"Could not load dependency 'smapi-lib/{dll.Name}'. Consider deleting and redownloading the SMAPI installer.", ex); } } return null; } } }