C# 如何在AppDomain.Unload(域)之后删除插件程序集

C# 如何在AppDomain.Unload(域)之后删除插件程序集,c#,plugins,assemblies,C#,Plugins,Assemblies,我有个奇怪的问题。 我想删除已加载的程序集(硬盘上的plugin.dll),但该程序集已被操作系统(vista)锁定,即使我已卸载它 f、 e 我还需要assemblyinfos,因为我不知道pluginassembly中的哪些类实现了IPlugin接口。在一个插件组件中应该可以有多个插件 Assembly assembly = appDomain.Load(assemblyName); if (assembly != null) { Type[] assemblyTypes = asse

我有个奇怪的问题。 我想删除已加载的程序集(硬盘上的plugin.dll),但该程序集已被操作系统(vista)锁定,即使我已卸载它

f、 e

我还需要assemblyinfos,因为我不知道pluginassembly中的哪些类实现了IPlugin接口。在一个插件组件中应该可以有多个插件

Assembly assembly = appDomain.Load(assemblyName);
if (assembly != null) {
   Type[] assemblyTypes = assembly.GetTypes();
   foreach (Type assemblyTyp in assemblyTypes) {
      if (typeof(IPlugin).IsAssignableFrom(assemblyTyp)) {
         IPlugin plugin = (IPlugin)Activator.CreateInstance(assemblyTyp);
         plugin.AssemblyName = assemblyNameWithEx;
         plugin.Host = this;
      }
   }
}
AppDomain.Unload(appDomain);
如何在不锁定程序集的情况下从appDomain获取assemblyinfos


最重要的是,我们要做的是有一个文件夹,用于监视程序集。添加程序集时,应用程序会将其复制到临时目录,并为其指定唯一的文件名,然后从该目录加载程序集

当应用程序首次加载时,它会尝试清除临时目录


我不认为这直接回答了您的问题,但它可能解决了您的问题。

如果您将程序集作为流加载,它应该可以工作

byte[] fileContent;
string path = "../../../test/bin/Debug/test.dll"; //Path to plugin assembly
using (FileStream dll = File.OpenRead(path))
{
   fileContent = new byte[dll.Length];
   dll.Read(fileContent, 0, (int)dll.Length);
}
Assembly assembly = appDomain.Load(fileContent);
File.Delete(path);
我想我知道答案了! 如果要删除加载的程序集,则来自Øyvind Skaar的答案将不起作用

而不是

using (FileStream dll = File.OpenRead(path))
{
   fileContent = new byte[dll.Length];
   dll.Read(fileContent, 0, (int)dll.Length);
}
Assembly assembly = appDomain.Load(fileContent);
你必须使用

byte[] b = File.ReadAllBytes(assemblyName);
assembly = Assembly.Load(b);

致以最诚挚的问候

我知道这个线程已经死了,但我目前正在处理这个问题,我刚刚得到了答案(凌晨1点30分…)

而且它实际上不会抛出任何异常!!! 希望有人会读到这篇文章,它会回答那个问题

请参见以下页面:

使用
LoaderOptimization.MultiDomainHost设置新的
AppDomain AppDomainSetup

例如


应该这样,但事实并非如此(File.Delete(path)处的UnauthorizedAccessException;如果不先加载程序集,您可以删除该文件吗?我尝试时效果很好,但您的程序比较短;)在卸载DLL和使用单独的AppDomain方面存在许多类似的问题,但当您确实想要删除DLL时,这些问题似乎不起作用。不管怎么说,这绝对奏效:)太好了!甚至不需要另一个应用程序域。如果使用另一个应用程序域,这不起作用,但这肯定是一种比使用应用程序域使事情复杂化更好的方法:)如果只能卸载应用程序域,我不清楚如何卸载.dll。使用字节数组的解决方案似乎没有使用任何AppDomain。有人能澄清一下吗?这是正确的。这应该行得通。另一种方法不起作用的原因是:当调用
app.Load()
时,程序集将加载到应用程序域
app
以及运行代码的应用程序域中。卸载
app
后,程序集仍将加载到其他应用程序域中。使用
app.DoCallBack
使代码在
app
中运行,从而导致程序集仅在
app
中加载。(来源:和)
byte[] b = File.ReadAllBytes(assemblyName);
assembly = Assembly.Load(b);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
AppDomain app = AppDomain.CreateDomain("YaCsi", null, setup);
app.DoCallBack(LoaderCallback);
AppDomain.Unload(app);
File.Delete("__YaCsi_Test01.dll");

static void LoaderCallback()
{
    byte[] raw = File.ReadAllBytes("__YaCsi_Test01.dll");
    Assembly yacsi = Assembly.Load(raw);
    ((IScript)yacsi.CreateInstance("Script")).Go();
}
domainnew = AppDomain.CreateDomain(newdomain_name, null, new AppDomainSetup {
        ApplicationName = newdomain_name,
        ApplicationBase = assembly_directory,
        ConfigurationFile = ConfigurationManager.OpenExeConfiguration(assemblylocation).FilePath,
        LoaderOptimization = LoaderOptimization.MultiDomainHost,
        ShadowCopyFiles = shadowcopy ? "true" : "false",
    }
);