簡體   English   中英

動態將c#程序集加載和卸載到appdomain中

[英]dynamically loading and unloading of c# assembly into appdomain

有許多類似的問題。 但是他們都已經歲了,今天不工作(不再嗎?)。

所以這是我的問題:我想將ac#程序集加載到內存中,並找出是否包含與我要使用的接口匹配的類型。 如果程序集包括此類,我將在我的主應用程序中引用並使用它。 如果不是,我想卸載dll,然后能夠刪除文件(從我的主應用程序中刪除,或者在應用程序運行時手動刪除)。

我的第一個實現只是省略了appdomain方法,但是它起作用了(無需刪除或替換程序集文件)。 然后,我嘗試按照各種示例中的說明加載程序集。 但是沒有,我能夠從磁盤上刪除不需要的程序集文件。

在應用程序中引用程序集時,根本無法卸載和刪除程序集,或者我做錯了什么。 這是我最后嘗試的:

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);
        }
    }
}

因此,此代碼將一直工作到File.Delete語句。 但隨后引發異常:

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.

現在,在編寫此問題時,我進行了更多測試-我試圖找出為什么我無法刪除程序集文件。 我發現它已被Visual Studio遠程調試器鎖定。

因此,第二個問題是:如何避免使用遠程調試器鎖定文件?

我發現Assembly.LoadFile(...)將鎖定文件,甚至超出卸載AppDomain的程度。

我的解決方案是先將程序集字節加載到內存中,然后再將其加載到AppDomain中:

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

這樣,文件就永遠不會被鎖定,您可以刪除它,等等。

有更好的回答類似的問題在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM