mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Use DOORSTOP_DLL_SEARCH_DIRS for preloader patching and typeloading
This commit is contained in:
1 parent
9ca5720cd1
commit
b920999686
7 files changed
+45
-8
No files matched your search
@@ -45,7 +45,7 @@ namespace BepInEx.Preloader
|
||||
|
||||
string bepinPath = Utility.ParentDirectory(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH), 2);
|
||||
|
||||
Paths.SetExecutablePath(EnvVars.DOORSTOP_PROCESS_PATH, bepinPath, EnvVars.DOORSTOP_MANAGED_FOLDER_DIR);
|
||||
Paths.SetExecutablePath(EnvVars.DOORSTOP_PROCESS_PATH, bepinPath, EnvVars.DOORSTOP_MANAGED_FOLDER_DIR, EnvVars.DOORSTOP_DLL_SEARCH_DIRS);
|
||||
|
||||
LoadCriticalAssemblies();
|
||||
AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BepInEx.Preloader
|
||||
{
|
||||
@@ -22,12 +23,18 @@ namespace BepInEx.Preloader
|
||||
/// Full path to the game executable currently running.
|
||||
/// </summary>
|
||||
public static string DOORSTOP_PROCESS_PATH { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of paths where Mono searches DLLs from before assembly resolvers are invoked.
|
||||
/// </summary>
|
||||
public static string[] DOORSTOP_DLL_SEARCH_DIRS { get; private set; }
|
||||
|
||||
internal static void LoadVars()
|
||||
{
|
||||
DOORSTOP_INVOKE_DLL_PATH = Environment.GetEnvironmentVariable("DOORSTOP_INVOKE_DLL_PATH");
|
||||
DOORSTOP_MANAGED_FOLDER_DIR = Environment.GetEnvironmentVariable("DOORSTOP_MANAGED_FOLDER_DIR");
|
||||
DOORSTOP_PROCESS_PATH = Environment.GetEnvironmentVariable("DOORSTOP_PROCESS_PATH");
|
||||
DOORSTOP_DLL_SEARCH_DIRS = Environment.GetEnvironmentVariable("DOORSTOP_DLL_SEARCH_DIRS")?.Split(Path.PathSeparator) ?? new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,14 +203,14 @@ namespace BepInEx.Preloader.Patching
|
||||
/// <summary>
|
||||
/// Applies patchers to all assemblies in the given directory and loads patched assemblies into memory.
|
||||
/// </summary>
|
||||
/// <param name="directory">Directory to load CLR assemblies from.</param>
|
||||
public static void PatchAndLoad(string directory)
|
||||
/// <param name="directories">Directories to load CLR assemblies from in their search order.</param>
|
||||
public static void PatchAndLoad(params string[] directories)
|
||||
{
|
||||
// First, load patchable assemblies into Cecil
|
||||
// Ignore case for keys (dll filenames) to account for running on *nix
|
||||
var assemblies = new Dictionary<string, AssemblyDefinition>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
foreach (string assemblyPath in Directory.GetFiles(directory, "*.dll"))
|
||||
foreach (string assemblyPath in Utility.GetUniqueFilesInDirectories(directories, "*.dll"))
|
||||
{
|
||||
AssemblyDefinition assembly;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace BepInEx.Preloader
|
||||
|
||||
Logger.LogInfo($"{AssemblyPatcher.PatcherPlugins.Count} patcher plugin{(AssemblyPatcher.PatcherPlugins.Count == 1 ? "" : "s")} loaded");
|
||||
|
||||
AssemblyPatcher.PatchAndLoad(Paths.ManagedPath);
|
||||
AssemblyPatcher.PatchAndLoad(Paths.DllSearchPaths);
|
||||
AssemblyPatcher.DisposePatchers();
|
||||
|
||||
Logger.LogMessage("Preloader finished");
|
||||
|
||||
@@ -70,10 +70,13 @@ namespace BepInEx.Bootstrap
|
||||
{
|
||||
if (Utility.TryParseAssemblyName(reference.FullName, out var name) &&
|
||||
(Utility.TryResolveDllAssembly(name, Paths.BepInExAssemblyDirectory, ReaderParameters, out var assembly) ||
|
||||
Utility.TryResolveDllAssembly(name, Paths.PluginPath, ReaderParameters, out assembly) ||
|
||||
Utility.TryResolveDllAssembly(name, Paths.ManagedPath, ReaderParameters, out assembly)))
|
||||
Utility.TryResolveDllAssembly(name, Paths.PluginPath, ReaderParameters, out assembly)))
|
||||
return assembly;
|
||||
|
||||
foreach (string dllSearchPath in Paths.DllSearchPaths)
|
||||
if (Utility.TryResolveDllAssembly(name, dllSearchPath, ReaderParameters, out assembly))
|
||||
return assembly;
|
||||
|
||||
return AssemblyResolve?.Invoke(sender, reference);
|
||||
};
|
||||
}
|
||||
|
||||
+8
-1
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using MonoMod.Utils;
|
||||
|
||||
@@ -9,7 +10,7 @@ namespace BepInEx
|
||||
/// </summary>
|
||||
public static class Paths
|
||||
{
|
||||
internal static void SetExecutablePath(string executablePath, string bepinRootPath = null, string managedPath = null)
|
||||
internal static void SetExecutablePath(string executablePath, string bepinRootPath = null, string managedPath = null, string[] dllSearchPath = null)
|
||||
{
|
||||
ExecutablePath = executablePath;
|
||||
ProcessName = Path.GetFileNameWithoutExtension(executablePath);
|
||||
@@ -27,6 +28,7 @@ namespace BepInEx
|
||||
BepInExAssemblyDirectory = Path.Combine(BepInExRootPath, "core");
|
||||
BepInExAssemblyPath = Path.Combine(BepInExAssemblyDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.dll");
|
||||
CachePath = Path.Combine(BepInExRootPath, "cache");
|
||||
DllSearchPaths = (dllSearchPath ?? new string[0]).Concat(new[] { ManagedPath }).Distinct().ToArray();
|
||||
}
|
||||
|
||||
internal static void SetManagedPath(string managedPath)
|
||||
@@ -41,6 +43,11 @@ namespace BepInEx
|
||||
PluginPath = Utility.CombinePaths(BepInExRootPath, pluginPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of directories from where Mono will search assemblies before assembly resolving is invoked.
|
||||
/// </summary>
|
||||
public static string[] DllSearchPaths { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The directory that the core BepInEx DLLs reside in.
|
||||
/// </summary>
|
||||
|
||||
@@ -293,5 +293,25 @@ namespace BepInEx
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets unique files in all given directories. If the file with the same name exists in multiple directories,
|
||||
/// only the first occurrence is returned.
|
||||
/// </summary>
|
||||
/// <param name="directories">Directories to search from.</param>
|
||||
/// <param name="pattern">File pattern to search.</param>
|
||||
/// <returns>Collection of all files in the directories.</returns>
|
||||
public static IEnumerable<string> GetUniqueFilesInDirectories(IEnumerable<string> directories, string pattern = "*")
|
||||
{
|
||||
var result = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (string directory in directories)
|
||||
foreach (string file in Directory.GetFiles(directory, pattern))
|
||||
{
|
||||
string fileName = Path.GetFileName(file);
|
||||
if (!result.ContainsKey(fileName))
|
||||
result[fileName] = file;
|
||||
}
|
||||
return result.Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user