diff --git a/src/dscom.client/AssemblyResolver.cs b/src/dscom.client/AssemblyResolver.cs index 6c53ab7..0b0a50b 100644 --- a/src/dscom.client/AssemblyResolver.cs +++ b/src/dscom.client/AssemblyResolver.cs @@ -1,11 +1,11 @@ // Copyright 2022 dSPACE GmbH, Mark Lechtermann, Matthias Nissen and Contributors -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -13,6 +13,7 @@ // limitations under the License. using System.Reflection; +using System.Runtime.Loader; namespace dSPACE.Runtime.InteropServices; @@ -21,46 +22,59 @@ namespace dSPACE.Runtime.InteropServices; /// internal sealed class AssemblyResolver : IDisposable { + private readonly AssemblyLoadContext _context; private bool _disposedValue; internal AssemblyResolver(TypeLibConverterOptions options) { Options = options; - AppDomain.CurrentDomain.AssemblyResolve += ResolveEventHandler; + _context = new AssemblyLoadContext("dscom", true); + _context.Resolving += Context_Resolving; } - public TypeLibConverterOptions Options { get; } - - private Assembly? ResolveEventHandler(object? sender, ResolveEventArgs args) + private Assembly? Context_Resolving(AssemblyLoadContext context, AssemblyName name) { - var name = args.Name; - var fileNameWithoutExtension = new AssemblyName(name).Name; + var dir = Path.GetDirectoryName(Options.Assembly); + + var asmPaths = Options.ASMPath; + if (Directory.Exists(dir)) + { + asmPaths = asmPaths.Prepend(dir).ToArray(); + } - foreach (var path in Options.ASMPath) + foreach (var path in asmPaths) { - var dllToLoad = Path.Combine(path, $"{fileNameWithoutExtension}.dll"); + var dllToLoad = Path.Combine(path, $"{name.Name}.dll"); if (File.Exists(dllToLoad)) { - return Assembly.LoadFrom(dllToLoad); + return _context.LoadFromAssemblyPath(dllToLoad); } - var exeToLoad = Path.Combine(path, $"{fileNameWithoutExtension}.exe"); + var exeToLoad = Path.Combine(path, $"{name.Name}.exe"); if (File.Exists(exeToLoad)) { - return Assembly.LoadFrom(exeToLoad); + return _context.LoadFromAssemblyPath(exeToLoad); } } return null; } + public Assembly LoadAssembly(string path) + { + return _context.LoadFromAssemblyPath(path); + } + + public TypeLibConverterOptions Options { get; } + private void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { - AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= ResolveEventHandler; + _context.Resolving -= Context_Resolving; + _context.Unload(); } _disposedValue = true; diff --git a/src/dscom.client/Program.cs b/src/dscom.client/Program.cs index 5710d20..7b5ec88 100644 --- a/src/dscom.client/Program.cs +++ b/src/dscom.client/Program.cs @@ -1,11 +1,11 @@ // Copyright 2022 dSPACE GmbH, Mark Lechtermann, Matthias Nissen and Contributors -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,7 +16,6 @@ using System.CommandLine.NamingConventionBinder; using System.CommandLine.Parsing; using System.Diagnostics; -using System.Reflection; using System.Runtime.InteropServices; namespace dSPACE.Runtime.InteropServices; @@ -161,7 +160,7 @@ private static void ConfigureTLBExportHandler(Command tlbexportCommand) throw new FileNotFoundException($"File {options.Assembly} not found."); } - var assembly = Assembly.LoadFrom(options.Assembly); + var assembly = assemblyResolver.LoadAssembly(options.Assembly); var typeLibConverter = new TypeLibConverter(); var nameResolver = options.Names.Any() ? NameResolver.Create(options.Names) : NameResolver.Create(assembly); var typeLib = typeLibConverter.ConvertAssemblyToTypeLib(assembly, options, new TypeLibExporterNotifySink(options, nameResolver));