summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-01-16 22:56:48 -0500
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-01-16 22:56:48 -0500
commit95f4513727193d0048848d10ded465527a4969c9 (patch)
treebbfc64126c9510e27ad867b74fe397d31b36c03e /src
parent85f8631beefb5f97088fcecabb32bb8d2829a2fe (diff)
downloadSMAPI-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.cs38
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)
{