mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-19 15:51:45 +00:00
Move .NET framework common entrypoint code to shared project, and add silent exception logging
This commit is contained in:
8 files changed
+230
-283
No files matched your search
@@ -17,4 +17,8 @@
|
||||
<ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\BepInEx.NetLauncher.Shared\BepInEx.NetLauncher.Shared.projitems" Label="Shared" />
|
||||
|
||||
<Import Project="..\BepInEx.Shared\BepInEx.Shared.projitems" Label="Shared" />
|
||||
|
||||
</Project>
|
||||
@@ -2,10 +2,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.NetCore;
|
||||
using BepInEx.NetLauncher.Shared;
|
||||
using BepInEx.Preloader.Core;
|
||||
|
||||
internal class StartupHook
|
||||
@@ -14,9 +13,11 @@ internal class StartupHook
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
var silentExceptionLog = $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log";
|
||||
|
||||
try
|
||||
{
|
||||
string filename;
|
||||
string filename, gameDirectory;
|
||||
|
||||
//#if DEBUG
|
||||
// filename =
|
||||
@@ -28,63 +29,24 @@ internal class StartupHook
|
||||
// ResolveDirectories.Add(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName));
|
||||
//#else
|
||||
filename = Process.GetCurrentProcess().MainModule.FileName;
|
||||
ResolveDirectories.Add(Path.Combine(Path.GetDirectoryName(filename), "BepInEx", "core"));
|
||||
gameDirectory = Path.GetDirectoryName(filename);
|
||||
ResolveDirectories.Add(Path.Combine(gameDirectory, "BepInEx", "core"));
|
||||
//#endif
|
||||
|
||||
silentExceptionLog = Path.Combine(gameDirectory, silentExceptionLog);
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += RemoteResolve;
|
||||
AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.RemoteResolve(ResolveDirectories);
|
||||
|
||||
NetCorePreloaderRunner.OuterMain(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
File.WriteAllText(silentExceptionLog, ex.ToString());
|
||||
|
||||
Console.WriteLine("Unhandled exception");
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static Assembly RemoteResolve(object sender, ResolveEventArgs reference)
|
||||
{
|
||||
var assemblyName = new AssemblyName(reference.Name);
|
||||
|
||||
foreach (var directory in ResolveDirectories)
|
||||
{
|
||||
if (!Directory.Exists(directory))
|
||||
continue;
|
||||
|
||||
var potentialDirectories = new List<string> { directory };
|
||||
|
||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||
|
||||
var potentialFiles = potentialDirectories.Select(x => Path.Combine(x, $"{assemblyName.Name}.dll"))
|
||||
.Concat(potentialDirectories.Select(x =>
|
||||
Path
|
||||
.Combine(x,
|
||||
$"{assemblyName.Name}.exe")));
|
||||
|
||||
foreach (var path in potentialFiles)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
continue;
|
||||
|
||||
Assembly assembly;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = Assembly.LoadFrom(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assembly.GetName().Name == assemblyName.Name)
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
namespace BepInEx.NetCore
|
||||
@@ -93,14 +55,14 @@ namespace BepInEx.NetCore
|
||||
{
|
||||
internal static void PreloaderMain()
|
||||
{
|
||||
ConsoleManager.Initialize(false, false);
|
||||
|
||||
ConsoleManager.CreateConsole();
|
||||
|
||||
Logger.Listeners.Add(new ConsoleLogListener());
|
||||
|
||||
try
|
||||
{
|
||||
ConsoleManager.Initialize(false, false);
|
||||
|
||||
ConsoleManager.CreateConsole();
|
||||
|
||||
Logger.Listeners.Add(new ConsoleLogListener());
|
||||
|
||||
NetCorePreloader.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -116,87 +78,9 @@ namespace BepInEx.NetCore
|
||||
|
||||
Paths.SetExecutablePath(filename);
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
|
||||
AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.LocalResolve;
|
||||
|
||||
PreloaderMain();
|
||||
}
|
||||
|
||||
private static Assembly LocalResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name);
|
||||
|
||||
var foundAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.FirstOrDefault(x => x.GetName().Name == assemblyName.Name);
|
||||
|
||||
if (foundAssembly != null)
|
||||
return foundAssembly;
|
||||
|
||||
if (LocalUtility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out foundAssembly)
|
||||
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out foundAssembly)
|
||||
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out foundAssembly))
|
||||
return foundAssembly;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic helper properties and methods.
|
||||
/// </summary>
|
||||
public static class LocalUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Try to resolve and load the given assembly DLL.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||
/// <param name="directory">Directory to search the assembly from.</param>
|
||||
/// <param name="assembly">The loaded assembly.</param>
|
||||
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||
private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName,
|
||||
string directory,
|
||||
Func<string, T> loader,
|
||||
out T assembly) where T : class
|
||||
{
|
||||
assembly = null;
|
||||
|
||||
if (!Directory.Exists(directory))
|
||||
return false;
|
||||
|
||||
var potentialDirectories = new List<string> { directory };
|
||||
|
||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||
|
||||
foreach (var subDirectory in potentialDirectories)
|
||||
{
|
||||
var path = Path.Combine(subDirectory, $"{assemblyName.Name}.dll");
|
||||
|
||||
if (!File.Exists(path))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = loader(path);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to resolve and load the given assembly DLL.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||
/// <param name="directory">Directory to search the assembly from.</param>
|
||||
/// <param name="assembly">The loaded assembly.</param>
|
||||
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||
public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly) =>
|
||||
TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>067bcc8c-fc25-4929-b4f4-c6a5a7496994</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>BepInEx.NetLauncher.Shared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SharedEntrypoint.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>067bcc8c-fc25-4929-b4f4-c6a5a7496994</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<PropertyGroup />
|
||||
<Import Project="BepInEx.NetLauncher.Shared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
// This code is shared between the .NET Framework launcher and the .NET Core entrypoint projects.
|
||||
// However, it cannot be placed in the NetLauncher.Common project because this has to do with assembly resolution,
|
||||
// and placing this logic inside of an external assembly will cause a crash.
|
||||
// A shared project is the only way to deduplicate code here
|
||||
|
||||
namespace BepInEx.NetLauncher.Shared
|
||||
{
|
||||
internal static class SharedEntrypoint
|
||||
{
|
||||
public static ResolveEventHandler RemoteResolve(List<string> resolveDirectories)
|
||||
{
|
||||
return (sender, args) => RemoteResolveInternal(sender, args, resolveDirectories);
|
||||
}
|
||||
|
||||
private static Assembly RemoteResolveInternal(object sender, ResolveEventArgs reference, List<string> resolveDirectories)
|
||||
{
|
||||
var assemblyName = new AssemblyName(reference.Name);
|
||||
|
||||
foreach (var directory in resolveDirectories)
|
||||
{
|
||||
if (!Directory.Exists(directory))
|
||||
continue;
|
||||
|
||||
var potentialDirectories = new List<string> { directory };
|
||||
|
||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||
|
||||
var potentialFiles = potentialDirectories.Select(x => Path.Combine(x, $"{assemblyName.Name}.dll"))
|
||||
.Concat(potentialDirectories.Select(x =>
|
||||
Path
|
||||
.Combine(x,
|
||||
$"{assemblyName.Name}.exe")));
|
||||
|
||||
foreach (var path in potentialFiles)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
continue;
|
||||
|
||||
Assembly assembly;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = Assembly.LoadFrom(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assembly.GetName().Name == assemblyName.Name)
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Assembly LocalResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name);
|
||||
|
||||
var foundAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.FirstOrDefault(x => x.GetName().Name == assemblyName.Name);
|
||||
|
||||
if (foundAssembly != null)
|
||||
return foundAssembly;
|
||||
|
||||
if (LocalUtility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out foundAssembly)
|
||||
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out foundAssembly)
|
||||
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out foundAssembly))
|
||||
return foundAssembly;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Generic helper properties and methods.
|
||||
/// </summary>
|
||||
internal static class LocalUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Try to resolve and load the given assembly DLL.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||
/// <param name="directory">Directory to search the assembly from.</param>
|
||||
/// <param name="assembly">The loaded assembly.</param>
|
||||
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||
private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName,
|
||||
string directory,
|
||||
Func<string, T> loader,
|
||||
out T assembly) where T : class
|
||||
{
|
||||
assembly = null;
|
||||
|
||||
if (!Directory.Exists(directory))
|
||||
return false;
|
||||
|
||||
var potentialDirectories = new List<string> { directory };
|
||||
|
||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||
|
||||
foreach (var subDirectory in potentialDirectories)
|
||||
{
|
||||
var path = Path.Combine(subDirectory, $"{assemblyName.Name}.dll");
|
||||
|
||||
if (!File.Exists(path))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = loader(path);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to resolve and load the given assembly DLL.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||
/// <param name="directory">Directory to search the assembly from.</param>
|
||||
/// <param name="assembly">The loaded assembly.</param>
|
||||
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||
public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly) =>
|
||||
TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
||||
}
|
||||
}
|
||||
@@ -31,4 +31,5 @@
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\BepInEx.Shared\BepInEx.Shared.projitems" Label="Shared" />
|
||||
<Import Project="..\BepInEx.NetLauncher.Shared\BepInEx.NetLauncher.Shared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
+31
-149
@@ -2,63 +2,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.NetLauncher.Shared;
|
||||
using BepInEx.Preloader.Core;
|
||||
|
||||
namespace BepInEx.NetLauncher;
|
||||
|
||||
internal static class NetPreloaderRunner
|
||||
{
|
||||
internal static void PreloaderMain(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Listeners.Add(new ConsoleLogListener());
|
||||
|
||||
ConsoleManager.Initialize(true, false);
|
||||
|
||||
NetPreloader.Start(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PreloaderLogger.Log.Log(LogLevel.Fatal, "Unhandled exception");
|
||||
PreloaderLogger.Log.Log(LogLevel.Fatal, ex);
|
||||
Program.ReadExit();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OuterMain(string[] args, string filename)
|
||||
{
|
||||
PlatformUtils.SetPlatform();
|
||||
|
||||
Paths.SetExecutablePath(filename);
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
|
||||
|
||||
PreloaderMain(args);
|
||||
}
|
||||
|
||||
private static Assembly LocalResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name);
|
||||
|
||||
var foundAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.FirstOrDefault(x => x.GetName().Name == assemblyName.Name);
|
||||
|
||||
if (foundAssembly != null)
|
||||
return foundAssembly;
|
||||
|
||||
if (LocalUtility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out foundAssembly)
|
||||
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out foundAssembly)
|
||||
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out foundAssembly))
|
||||
return foundAssembly;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Program
|
||||
{
|
||||
public static List<string> ResolveDirectories { get; set; } = new()
|
||||
@@ -75,6 +24,8 @@ internal class Program
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var silentExceptionLog = $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log";
|
||||
|
||||
try
|
||||
{
|
||||
string filename;
|
||||
@@ -88,122 +39,53 @@ internal class Program
|
||||
// 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"));
|
||||
filename = Process.GetCurrentProcess().MainModule.FileName;
|
||||
ResolveDirectories.Add(Path.Combine(Path.GetDirectoryName(filename), "BepInEx", "core"));
|
||||
#endif
|
||||
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += RemoteResolve;
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.RemoteResolve(ResolveDirectories);
|
||||
|
||||
NetPreloaderRunner.OuterMain(args, filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
File.WriteAllText(silentExceptionLog, ex.ToString());
|
||||
|
||||
Console.WriteLine("Unhandled exception");
|
||||
Console.WriteLine(ex);
|
||||
ReadExit();
|
||||
}
|
||||
}
|
||||
|
||||
private static Assembly RemoteResolve(object sender, ResolveEventArgs reference)
|
||||
{
|
||||
var assemblyName = new AssemblyName(reference.Name);
|
||||
|
||||
foreach (var directory in ResolveDirectories)
|
||||
{
|
||||
if (!Directory.Exists(directory))
|
||||
continue;
|
||||
|
||||
var potentialDirectories = new List<string> { directory };
|
||||
|
||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||
|
||||
var potentialFiles = potentialDirectories.Select(x => Path.Combine(x, $"{assemblyName.Name}.dll"))
|
||||
.Concat(potentialDirectories.Select(x =>
|
||||
Path
|
||||
.Combine(x,
|
||||
$"{assemblyName.Name}.exe")));
|
||||
|
||||
foreach (var path in potentialFiles)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
continue;
|
||||
|
||||
Assembly assembly;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = Assembly.LoadFrom(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assembly.GetName().Name == assemblyName.Name)
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic helper properties and methods.
|
||||
/// </summary>
|
||||
public static class LocalUtility
|
||||
internal static class NetPreloaderRunner
|
||||
{
|
||||
/// <summary>
|
||||
/// Try to resolve and load the given assembly DLL.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||
/// <param name="directory">Directory to search the assembly from.</param>
|
||||
/// <param name="assembly">The loaded assembly.</param>
|
||||
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||
private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName,
|
||||
string directory,
|
||||
Func<string, T> loader,
|
||||
out T assembly) where T : class
|
||||
internal static void PreloaderMain(string[] args)
|
||||
{
|
||||
assembly = null;
|
||||
Logger.Listeners.Add(new ConsoleLogListener());
|
||||
|
||||
if (!Directory.Exists(directory))
|
||||
return false;
|
||||
ConsoleManager.Initialize(true, false);
|
||||
|
||||
var potentialDirectories = new List<string> { directory };
|
||||
|
||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||
|
||||
foreach (var subDirectory in potentialDirectories)
|
||||
try
|
||||
{
|
||||
var path = Path.Combine(subDirectory, $"{assemblyName.Name}.dll");
|
||||
|
||||
if (!File.Exists(path))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = loader(path);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
NetPreloader.Start(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PreloaderLogger.Log.Log(LogLevel.Fatal, "Unhandled exception");
|
||||
PreloaderLogger.Log.Log(LogLevel.Fatal, ex);
|
||||
Program.ReadExit();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to resolve and load the given assembly DLL.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||
/// <param name="directory">Directory to search the assembly from.</param>
|
||||
/// <param name="assembly">The loaded assembly.</param>
|
||||
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||
public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly) =>
|
||||
TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
||||
internal static void OuterMain(string[] args, string filename)
|
||||
{
|
||||
PlatformUtils.SetPlatform();
|
||||
|
||||
Paths.SetExecutablePath(filename);
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += SharedEntrypoint.LocalResolve;
|
||||
|
||||
PreloaderMain(args);
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -35,12 +35,18 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BepInEx.Shared", "BepInEx.S
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInEx.NetLauncher.Common", "BepInEx.NetLauncher.Common\BepInEx.NetLauncher.Common.csproj", "{76EB1952-7826-471C-9CF3-815D094DA077}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.NetCore", "BepInEx.NetCore\BepInEx.NetCore.csproj", "{08083F40-98AA-4176-BA01-817C18C35C7F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInEx.NetCore", "BepInEx.NetCore\BepInEx.NetCore.csproj", "{08083F40-98AA-4176-BA01-817C18C35C7F}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BepInEx.NetLauncher.Shared", "BepInEx.NetLauncher.Shared\BepInEx.NetLauncher.Shared.shproj", "{067BCC8C-FC25-4929-B4F4-C6A5A7496994}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
BepInEx.NetLauncher.Shared\BepInEx.NetLauncher.Shared.projitems*{067bcc8c-fc25-4929-b4f4-c6a5a7496994}*SharedItemsImports = 13
|
||||
BepInEx.NetLauncher.Shared\BepInEx.NetLauncher.Shared.projitems*{08083f40-98aa-4176-ba01-817c18c35c7f}*SharedItemsImports = 5
|
||||
BepInEx.Shared\BepInEx.Shared.projitems*{08083f40-98aa-4176-ba01-817c18c35c7f}*SharedItemsImports = 5
|
||||
BepInEx.Shared\BepInEx.Shared.projitems*{15f8bc38-a761-4f93-8903-1b531ac5d9f9}*SharedItemsImports = 5
|
||||
BepInEx.Shared\BepInEx.Shared.projitems*{429d5f83-7fec-4d09-ab82-e868eb61af59}*SharedItemsImports = 5
|
||||
BepInEx.NetLauncher.Shared\BepInEx.NetLauncher.Shared.projitems*{490b052b-7f23-4052-ad04-613856618901}*SharedItemsImports = 5
|
||||
BepInEx.Shared\BepInEx.Shared.projitems*{490b052b-7f23-4052-ad04-613856618901}*SharedItemsImports = 5
|
||||
BepInEx.Shared\BepInEx.Shared.projitems*{4ffba620-f5ed-47f9-b90c-dad1316fd9b9}*SharedItemsImports = 5
|
||||
BepInEx.Shared\BepInEx.Shared.projitems*{5c7847fb-c16d-47bd-bb17-1045669f9aa7}*SharedItemsImports = 13
|
||||
@@ -131,6 +137,7 @@ Global
|
||||
{429D5F83-7FEC-4D09-AB82-E868EB61AF59} = {D5F47CFC-E4F3-46EE-B4F3-2474CF7D9E2C}
|
||||
{76EB1952-7826-471C-9CF3-815D094DA077} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
|
||||
{08083F40-98AA-4176-BA01-817C18C35C7F} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
|
||||
{067BCC8C-FC25-4929-B4F4-C6A5A7496994} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {55AC11EF-F568-4C79-A356-7ED9510145B1}
|
||||
|
||||
Reference in new issue
Block a user