有許多類似的問題。但他們都已經幾年了,今天不再工作了(再?)。動態加載和卸載C#程序集到應用程序域
所以這裏是我的問題: 我想加載一個c#程序集到內存中,並找出它是否包含匹配我想要使用的接口的類型。如果程序集包含這個類的類型,我參考並在我的主應用程序中使用它。如果沒有,我想卸載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遠程調試器鎖定。
所以第二個問題是:如何避免用遠程調試器鎖定文件?
你好@John,我用你的代碼替換了我的例子中的代碼,它工作。 這是「appdomain」方法的解決方案。但它應該不使用appdomain。 –
@WolfgangRoth雖然它應該適用於兩者,但請注意(正如[鏈接的答案](https://stackoverflow.com/a/18935973/3181933)所述),除非它已被加載,否則無法卸載程序集,除非它在AppDomain中。 [MSDN同意](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/assemblies-gac/how-to-load-and-unload-assemblies) – john
我還沒有調查裝配的多重負荷的影響。但我的程序集加載的主要想法是能夠實現插件到我的代碼,可以由用戶交換。每當用戶更新插件列表時,應該添加新的插件,並且應該從顯示給用戶的列表中刪除舊的插件 - 它可能是,應用程序將無法替換僅在實現方面不同的組件,但是其他人有相同的命名空間和名字......明天可能會試試這個。 –