gpt4 book ai didi

c# - 将 c# 程序集动态加载和卸载到 appdomain

转载 作者:行者123 更新时间:2023-12-05 01:44:20 25 4
gpt4 key购买 nike

类似的问题还有很多。但他们都老了,今天(不再?)不工作了。

所以这是我的问题:我想将一个 c# 程序集加载到内存中,并查明它是否包含与我要使用的接口(interface)匹配的类型。如果程序集包含此类类型,我会在我的主应用程序中引用并使用它。如果没有,我想卸载 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);

这样文件永远不会被锁定,你可以删除它等等。

类似问题有更好的答案here .

关于c# - 将 c# 程序集动态加载和卸载到 appdomain,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46661585/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com