Merge pull request #363 from Mbucari/master

Change assembly loadig
This commit is contained in:
rmcrackan 2022-08-18 13:36:08 -04:00 committed by GitHub
commit 959e31972e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -32,7 +32,7 @@ namespace LibationFileManager
: Configuration.IsMacOs ? a => Path.GetFileName(a).StartsWithInsensitive("mac") || Path.GetFileName(a).StartsWithInsensitive("osx") : Configuration.IsMacOs ? a => Path.GetFileName(a).StartsWithInsensitive("mac") || Path.GetFileName(a).StartsWithInsensitive("osx")
: _ => false; : _ => false;
private const string CONFIG_APP_ENDING = "ConfigApp.exe"; private const string CONFIG_APP_ENDING = "ConfigApp.dll";
private static List<ProcessModule> ModuleList { get; } = new(); private static List<ProcessModule> ModuleList { get; } = new();
static InteropFactory() static InteropFactory()
{ {
@ -41,16 +41,26 @@ namespace LibationFileManager
// nothing to load // nothing to load
if (configApp is null) if (configApp is null)
{
Serilog.Log.Logger.Error($"Unable to locate *{CONFIG_APP_ENDING}");
return; return;
}
/*
* Commented code used to locate assemblies from the *ConfigApp.exe's module list.
* Use this method to locate dependencies when they are not in Libation's program files directory.
#if DEBUG
// runs the exe and gets the exe's loaded modules // runs the exe and gets the exe's loaded modules
ModuleList = LoadModuleList(Path.GetFileNameWithoutExtension(configApp)) ModuleList = LoadModuleList(Path.GetFileNameWithoutExtension(configApp))
.OrderBy(x => x.ModuleName) .OrderBy(x => x.ModuleName)
.ToList(); .ToList();
#endif
*/
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
var configAppAssembly = Assembly.LoadFrom(Path.ChangeExtension(configApp, "dll")); var configAppAssembly = Assembly.LoadFrom(configApp);
var type = typeof(IInteropFunctions); var type = typeof(IInteropFunctions);
InteropFunctionsType = configAppAssembly InteropFunctionsType = configAppAssembly
.GetTypes() .GetTypes()
@ -60,21 +70,19 @@ namespace LibationFileManager
{ {
var here = Path.GetDirectoryName(Environment.ProcessPath); var here = Path.GetDirectoryName(Environment.ProcessPath);
// find '*ConfigApp.exe' files // find '*ConfigApp.dll' files
var exes = var appName =
Directory.EnumerateFiles(here, $"*{CONFIG_APP_ENDING}", SearchOption.TopDirectoryOnly) Directory.EnumerateFiles(here, $"*{CONFIG_APP_ENDING}", SearchOption.TopDirectoryOnly)
// sanity check. shouldn't ever be true // sanity check. shouldn't ever be true
.Except(new[] { Environment.ProcessPath }) .Except(new[] { Environment.ProcessPath })
.Where(exe => .FirstOrDefault(exe => MatchesOS(exe));
// has a corresponding dll
File.Exists(Path.ChangeExtension(exe, "dll")) return appName;
&& MatchesOS(exe)
)
.ToList();
var exeName = exes.FirstOrDefault();
return exeName;
} }
/*
* Use this method to locate dependencies when they are not in Libation's program files directory.
*
private static List<ProcessModule> LoadModuleList(string exeName) private static List<ProcessModule> LoadModuleList(string exeName)
{ {
var proc = new Process var proc = new Process
@ -111,16 +119,38 @@ namespace LibationFileManager
return modules; return modules;
} }
*/
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{ {
// e.g. "System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" // e.g. "System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
var asmName = args.Name.Split(',')[0]; var asmName = args.Name.Split(',')[0] + ".dll";
// `First` instead of `FirstOrDefault`. If it's not present we're going to fail anyway. May as well be here
var module = ModuleList.First(m => m.ModuleName.StartsWith(asmName));
return Assembly.LoadFrom(module.FileName); /*
* Commented code used to locate assemblies from the *ConfigApp.exe's module list.
* Use this method to locate dependencies when they are not in Libation's program files directory.
#if DEBUG
var modulePath = ModuleList.SingleOrDefault(m => m.ModuleName.EqualsInsensitive(asmName))?.FileName;
#else
*/
var here = Path.GetDirectoryName(Environment.ProcessPath);
// find the requested assembly in the program files directory
var modulePath =
Directory.EnumerateFiles(here, asmName, SearchOption.TopDirectoryOnly)
.SingleOrDefault();
//#endif
if (modulePath is null)
{
//Let the runtime handle any dll not found exceptions.
Serilog.Log.Logger.Error($"Unable to load module {args.Name}");
return null;
}
return Assembly.LoadFrom(modulePath);
} }
#endregion #endregion