|
@@ -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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|