diff --git a/Source/LibationFileManager/InteropFactory.cs b/Source/LibationFileManager/InteropFactory.cs index 6e5cf96b..d596c9ab 100644 --- a/Source/LibationFileManager/InteropFactory.cs +++ b/Source/LibationFileManager/InteropFactory.cs @@ -21,7 +21,7 @@ namespace LibationFileManager private static IInteropFunctions _create(params object[] values) => InteropFunctionsType is null ? new NullInteropFunctions() -//: values is null || values.Length == 0 ? Activator.CreateInstance(InteropFunctionsType) as IInteropFunctions + //: values is null || values.Length == 0 ? Activator.CreateInstance(InteropFunctionsType) as IInteropFunctions : Activator.CreateInstance(InteropFunctionsType, values) as IInteropFunctions; #region load types @@ -32,7 +32,7 @@ namespace LibationFileManager : Configuration.IsMacOs ? a => Path.GetFileName(a).StartsWithInsensitive("mac") || Path.GetFileName(a).StartsWithInsensitive("osx") : _ => false; - private const string CONFIG_APP_ENDING = "ConfigApp.exe"; + private const string CONFIG_APP_ENDING = "ConfigApp.dll"; private static List ModuleList { get; } = new(); static InteropFactory() { @@ -41,16 +41,26 @@ namespace LibationFileManager // nothing to load if (configApp is null) + { + Serilog.Log.Logger.Error($"Unable to locate *{CONFIG_APP_ENDING}"); return; + } - // runs the exe and gets the exe's loaded modules - ModuleList = LoadModuleList(Path.GetFileNameWithoutExtension(configApp)) - .OrderBy(x => x.ModuleName) - .ToList(); + /* + * 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 + ModuleList = LoadModuleList(Path.GetFileNameWithoutExtension(configApp)) + .OrderBy(x => x.ModuleName) + .ToList(); +#endif + */ AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; - var configAppAssembly = Assembly.LoadFrom(Path.ChangeExtension(configApp, "dll")); + var configAppAssembly = Assembly.LoadFrom(configApp); var type = typeof(IInteropFunctions); InteropFunctionsType = configAppAssembly .GetTypes() @@ -60,21 +70,19 @@ namespace LibationFileManager { var here = Path.GetDirectoryName(Environment.ProcessPath); - // find '*ConfigApp.exe' files - var exes = + // find '*ConfigApp.dll' files + var appName = Directory.EnumerateFiles(here, $"*{CONFIG_APP_ENDING}", SearchOption.TopDirectoryOnly) // sanity check. shouldn't ever be true .Except(new[] { Environment.ProcessPath }) - .Where(exe => - // has a corresponding dll - File.Exists(Path.ChangeExtension(exe, "dll")) - && MatchesOS(exe) - ) - .ToList(); - var exeName = exes.FirstOrDefault(); - return exeName; + .FirstOrDefault(exe => MatchesOS(exe)); + + return appName; } + /* + * Use this method to locate dependencies when they are not in Libation's program files directory. + * private static List LoadModuleList(string exeName) { var proc = new Process @@ -111,16 +119,38 @@ namespace LibationFileManager return modules; } + */ private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { // 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