diff --git a/BepInEx.Core/Bootstrap/TypeLoader.cs b/BepInEx.Core/Bootstrap/TypeLoader.cs index 2f1e4f4..3bc5a3b 100644 --- a/BepInEx.Core/Bootstrap/TypeLoader.cs +++ b/BepInEx.Core/Bootstrap/TypeLoader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -91,10 +91,19 @@ namespace BepInEx.Bootstrap Utility.TryResolveDllAssembly(name, Paths.ManagedPath, ReaderParameters, out assembly)) return assembly; - return - SearchDirectories.Any(dir => Utility.TryResolveDllAssembly(name, dir, ReaderParameters, out assembly)) - ? assembly - : AssemblyResolve?.Invoke(sender, reference); + foreach (var dir in SearchDirectories) + { + if (!Directory.Exists(dir)) + { + Logger.LogDebug($"Unable to resolve cecil search directory '{dir}'"); + continue; + } + + if (Utility.TryResolveDllAssembly(name, dir, ReaderParameters, out assembly)) + return assembly; + } + + return AssemblyResolve?.Invoke(sender, reference); } /// diff --git a/BepInEx.Core/Utility.cs b/BepInEx.Core/Utility.cs index 831b00b..9ec52f0 100644 --- a/BepInEx.Core/Utility.cs +++ b/BepInEx.Core/Utility.cs @@ -176,6 +176,9 @@ namespace BepInEx var potentialDirectories = new List {directory}; + if (!Directory.Exists(directory)) + return false; + potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories)); foreach (var subDirectory in potentialDirectories) diff --git a/BepInEx.NetLauncher/NetPreloader.cs b/BepInEx.NetLauncher/NetPreloader.cs index 0402cf3..c382c5f 100644 --- a/BepInEx.NetLauncher/NetPreloader.cs +++ b/BepInEx.NetLauncher/NetPreloader.cs @@ -2,12 +2,14 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.NetLauncher.RuntimeFixes; using BepInEx.Preloader.Core; using BepInEx.Preloader.Core.Logging; +using MonoMod.Utils; namespace BepInEx.NetLauncher { @@ -15,21 +17,15 @@ namespace BepInEx.NetLauncher { private static readonly ManualLogSource Log = PreloaderLogger.Log; - #region Config - - private static readonly ConfigEntry ConfigEntrypointExecutable = ConfigFile.CoreConfig.Bind( - "Preloader.Entrypoint", "Assembly", - null, - "The local filename of the .NET executable to target."); - - #endregion + [DllImport("Kernel32.dll")] + private static extern bool SetDllDirectory([MarshalAs(UnmanagedType.LPTStr)] string lpPathName); public static void Start(string[] args) { if (string.IsNullOrEmpty(ConfigEntrypointExecutable.Value)) { - Log.LogFatal("Entry executable was not set. Please set this in your config before launching the application"); + Log.LogFatal($"Entry executable was not set. Please set this in your config before launching the application"); Program.ReadExit(); return; } @@ -43,9 +39,18 @@ namespace BepInEx.NetLauncher return; } + Paths.SetExecutablePath(executablePath); Program.ResolveDirectories.Add(Paths.GameRootPath); - TypeLoader.SearchDirectories.Add(Paths.GameRootPath); + + foreach (var searchDir in Program.ResolveDirectories) + TypeLoader.SearchDirectories.Add(searchDir); + + if (PlatformHelper.Is(Platform.Windows)) + { + SetDllDirectory(Paths.GameRootPath); + } + Logger.Sources.Add(TraceLogSource.CreateSource()); @@ -81,7 +86,7 @@ namespace BepInEx.NetLauncher } else { - Log.LogDebug("Using entrypoint assembly from disk"); + Log.LogDebug("Using entrypoint assembly from disk"); entrypointAssembly = Assembly.LoadFrom(executablePath); } } @@ -95,7 +100,16 @@ namespace BepInEx.NetLauncher AssemblyFix.Execute(entrypointAssembly); - entrypointAssembly.EntryPoint.Invoke(null, new[] {args}); + entrypointAssembly.EntryPoint.Invoke(null, new [] { args }); } + + #region Config + + private static readonly ConfigEntry ConfigEntrypointExecutable = ConfigFile.CoreConfig.Bind( + "Preloader.Entrypoint", "Assembly", + null, + "The local filename of the .NET executable to target."); + + #endregion } } diff --git a/BepInEx.NetLauncher/Program.cs b/BepInEx.NetLauncher/Program.cs index e95db24..3887d06 100644 --- a/BepInEx.NetLauncher/Program.cs +++ b/BepInEx.NetLauncher/Program.cs @@ -78,14 +78,16 @@ namespace BepInEx.NetLauncher string filename; #if DEBUG - filename = - Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName)); + filename = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName)); + ResolveDirectories.Add(Path.GetDirectoryName(filename)); + // for debugging within VS + ResolveDirectories.Add(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)); #else filename = Process.GetCurrentProcess().MainModule.FileName; + ResolveDirectories.Add(Path.Combine(Path.GetDirectoryName(filename), "BepInEx", "Core")); #endif - ResolveDirectories.Add(Path.Combine(Path.GetDirectoryName(filename), "BepInEx", "Core")); AppDomain.CurrentDomain.AssemblyResolve += RemoteResolve; @@ -105,7 +107,10 @@ namespace BepInEx.NetLauncher foreach (var directory in ResolveDirectories) { - var potentialDirectories = new List {directory}; + if (!Directory.Exists(directory)) + continue; + + var potentialDirectories = new List { directory }; potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories)); @@ -120,7 +125,16 @@ namespace BepInEx.NetLauncher if (!File.Exists(path)) continue; - var assembly = Assembly.LoadFrom(path); + Assembly assembly; + + try + { + assembly = Assembly.LoadFrom(path); + } + catch (Exception ex) + { + continue; + } if (assembly.GetName().Name == assemblyName.Name) return assembly; diff --git a/BepInEx.NetLauncher/Utility.cs b/BepInEx.NetLauncher/Utility.cs index 7691f3a..38059f0 100644 --- a/BepInEx.NetLauncher/Utility.cs +++ b/BepInEx.NetLauncher/Utility.cs @@ -22,7 +22,10 @@ namespace BepInEx.NetLauncher { assembly = null; - var potentialDirectories = new List {directory}; + if (!Directory.Exists(directory)) + return false; + + var potentialDirectories = new List { directory }; potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories)); diff --git a/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs b/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs index 5d64b00..abbb5a2 100644 --- a/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs +++ b/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs @@ -270,7 +270,7 @@ namespace BepInEx.Preloader.Core { try { - assembly = AssemblyDefinition.ReadAssembly(path); + assembly = AssemblyDefinition.ReadAssembly(path, TypeLoader.ReaderParameters); return true; } catch (BadImageFormatException)