简体   繁体   中英

dynamically loading and unloading of c# assembly into appdomain

there are many similar questions like this one. But they are all years old and dont work (anymore?) today.

So here is my question: I want to load ac# assembly into memory and find out if it has types included that match an interface i want to use. If the assembly has this class type included, i reference and use it in my main application. If not, i want to unload the dll and then be able to delete the file (from my main application or by hand while the application is running).

My first implementation simply ommitted the appdomain approach, but it worked (without deleting or replacing assembly files). Then I tried to load the assemblies as described in various examples. But with none i was able to delete the not needed assembly files from disk.

Either it is simply not possible to unload and delete assemblies when they were referenced in an application or i am doing something wrong. This is what i tried at last:

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using ESTLogViewer_V2.Formulare;
using Parent;
namespace ESTLogViewer_V2
{
    static class Program
    {
        //<summary>
        //Der Haupteinstiegspunkt für die Anwendung.
        //</summary>
        [STAThread]
        static void Main()
        {
            LoadTest.Haupt(null);
        }
    }
}
namespace Parent
{
    public class Constants
    {
        // adjust
        public const string LIB_PATH = @"e:\PRJDOTNET4\ESTLogViewer V2\Plugins\LogFiles_Plugin.dll";
    }

    public interface ILoader
    {
        string Execute();
    }

    public class Loader : MarshalByRefObject, ILoader
    {
        public string Execute()
        {
            var assembly = Assembly.LoadFile(Constants.LIB_PATH);
            foreach (var t in assembly.GetTypes())
            {
                Debug.WriteLine(t.FullName);

            }
            return assembly.FullName;
        }
    }

    class LoadTest
    {
        public static void Haupt(string[] args)
        {
            var domain = AppDomain.CreateDomain("child");
            var loader = (ILoader)domain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
            Console.Out.WriteLine(loader.Execute());
            AppDomain.Unload(domain);
            domain = null;
            File.Delete(Constants.LIB_PATH);
        }
    }
}

So, this code works until the File.Delete statement. But then it throws an exception:

LogFiles_Plugin.clsSchritLogDateiSplitter
LogFiles_Plugin.clsLogFileMeldDateiSplitter
LogFiles_Plugin.clsLogFileMeldDateiSplitterNG
LogFiles_Plugin.clsAuftragsAnalyseSplitter
LogFiles_Plugin.clsAuftrag
LogFiles_Plugin.clsS_R_SignalSplitter
LogFiles_Plugin.clsLogFileGVMeldDateiSplitter
LogFiles_Plugin.clsLogFileGVTeleSplitter
LogFiles_Plugin.clsLogFileGVTeleSplitter+spalte
<PrivateImplementationDetails>{37CEBF0C-E73A-4FE7-B152-9A858E6C176D}
<PrivateImplementationDetails>{37CEBF0C-E73A-4FE7-B152-9A858E6C176D}+__StaticArrayInitTypeSize=6256
"ESTLogViewer V2.exe" (Verwaltet (v4.0.30319)): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll" geladen
Eine Ausnahme (erste Chance) des Typs "System.UnauthorizedAccessException" ist in mscorlib.dll aufgetreten.

Right now, while writing this question, i did some more tests - i tried to find out why i could not delete the assembly file. I found out, that it was locked by the visual studio remote debugger.

So the second question is: How to avoid locking the file with the remote debugger?

I found that Assembly.LoadFile(...) will lock the file, even beyond the point of unloading the AppDomain.

My solution is to first load the assembly bytes into memory, and then load it into the AppDomain:

var assemblyBytes = System.IO.File.ReadAllBytes("myassembly.dll");
var assembly = System.Reflection.Assembly.Load(assemblyBytes);

That way the file is never locked and you can delete it, etc.

There's a better answer to a similar question here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM