diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-01-16 22:56:48 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-01-16 22:56:48 -0500 |
commit | 95f4513727193d0048848d10ded465527a4969c9 (patch) | |
tree | bbfc64126c9510e27ad867b74fe397d31b36c03e /src | |
parent | 85f8631beefb5f97088fcecabb32bb8d2829a2fe (diff) | |
download | SMAPI-95f4513727193d0048848d10ded465527a4969c9.tar.gz SMAPI-95f4513727193d0048848d10ded465527a4969c9.tar.bz2 SMAPI-95f4513727193d0048848d10ded465527a4969c9.zip |
rewrite fallback assembly resolution
* SMAPI now also searches the root game folder for unresolved assemblies. This fixes an issue resolving the game DLL when the player's DLL version doesn't match the one used to compile SMAPI.
* The DLL search folders are now scanned once and cached to avoid repeated iterations on startup.
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI/Program.cs | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 67ff8322..0c90f2aa 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; @@ -16,7 +17,10 @@ namespace StardewModdingAPI ** Fields *********/ /// <summary>The absolute path to search for SMAPI's internal DLLs.</summary> - internal static readonly string DllSearchPath = EarlyConstants.InternalFilesPath; + private static readonly string DllSearchPath = EarlyConstants.InternalFilesPath; + + /// <summary>The assembly paths in the search folders indexed by assembly name.</summary> + private static Dictionary<string, string> AssemblyPathsByName; /********* @@ -57,16 +61,36 @@ namespace StardewModdingAPI /// <param name="e">The event arguments.</param> private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e) { - try + // cache assembly paths by name + if (Program.AssemblyPathsByName == null) { - AssemblyName name = new AssemblyName(e.Name); - foreach (FileInfo dll in new DirectoryInfo(Program.DllSearchPath).EnumerateFiles("*.dll")) + Program.AssemblyPathsByName = new(StringComparer.OrdinalIgnoreCase); + + foreach (string searchPath in new[] { EarlyConstants.ExecutionPath, Program.DllSearchPath }) { - if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.OrdinalIgnoreCase)) - return Assembly.LoadFrom(dll.FullName); + foreach (string dllPath in Directory.EnumerateFiles(searchPath, "*.dll")) + { + try + { + string curName = AssemblyName.GetAssemblyName(dllPath).Name; + if (curName != null) + Program.AssemblyPathsByName[curName] = dllPath; + } + catch + { + continue; + } + } } + } - return null; + // resolve + try + { + string searchName = new AssemblyName(e.Name).Name; + return searchName != null && Program.AssemblyPathsByName.TryGetValue(searchName, out string assemblyPath) + ? Assembly.LoadFrom(assemblyPath) + : null; } catch (Exception ex) { |