Add a minimal assembly resolver before running main preloader code

This commit is contained in:
ghorsington committed 2019-06-16 18:48:41 +03:00
1 parent b92ba3e6bf
commit ccb626073f
1 file changed
+44 -21
+44 -21
View File
@@ -5,16 +5,9 @@ using System.Reflection;
namespace BepInEx.Preloader
{
internal static class Entrypoint
internal static class PreloaderRunner
{
/// <summary>
/// The main entrypoint of BepInEx, called from Doorstop.
/// </summary>
/// <param name="args">
/// The arguments passed in from Doorstop. First argument is the path of the currently executing
/// process.
/// </param>
public static void Main(string[] args)
public static void PreloaderMain(string[] args)
{
EnvVars.LoadVars();
@@ -22,21 +15,10 @@ namespace BepInEx.Preloader
Paths.SetExecutablePath(args[0], bepinPath, EnvVars.DOORSTOP_MANAGED_FOLDER_DIR);
AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
Preloader.Run();
}
/// <summary>
/// A handler for <see cref="AppDomain.AssemblyResolve" /> to perform some special handling.
/// <para>
/// It attempts to check currently loaded assemblies (ignoring the version), and then checks the BepInEx/core path,
/// BepInEx/patchers path and the BepInEx folder, all in that order.
/// </para>
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <returns></returns>
internal static Assembly LocalResolve(object sender, ResolveEventArgs args)
private static Assembly LocalResolve(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name);
@@ -54,4 +36,45 @@ namespace BepInEx.Preloader
return null;
}
}
internal static class Entrypoint
{
private static string preloaderPath;
/// <summary>
/// The main entrypoint of BepInEx, called from Doorstop.
/// </summary>
/// <param name="args">
/// The arguments passed in from Doorstop. First argument is the path of the currently executing
/// process.
/// </param>
public static void Main(string[] args)
{
// Get the path of this DLL via Doorstop env var because Assembly.Location mangles non-ASCII characters on some versions of Mono for unknown reasons
preloaderPath = Path.GetDirectoryName(Path.GetFullPath(Environment.GetEnvironmentVariable("DOORSTOP_INVOKE_DLL_PATH")));
AppDomain.CurrentDomain.AssemblyResolve += ResolveCurrentDirectory;
// We have to use reflection and a separate startup class in order to not trigger premature assembly resolving
typeof(Entrypoint).Assembly.GetType($"BepInEx.Preloader.{nameof(PreloaderRunner)}")
?.GetMethod(nameof(PreloaderRunner.PreloaderMain))
?.Invoke(null, new object[] { args });
AppDomain.CurrentDomain.AssemblyResolve -= ResolveCurrentDirectory;
}
private static Assembly ResolveCurrentDirectory(object sender, ResolveEventArgs args)
{
var name = new AssemblyName(args.Name);
try
{
return Assembly.LoadFile(Path.Combine(preloaderPath, $"{name.Name}.dll"));
}
catch (Exception)
{
return null;
}
}
}
}