appDomain.Unload(domain)后如何删除pluginassembly

时间:2009-01-08 17:10:38

标签: c# plugins assemblies

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

f.e。

AppDomainSetup setup = new AppDomainSetup();
setup.ShadowCopyFiles = "true";
AppDomain appDomain = AppDomain.CreateDomain(assemblyName + "_AppDomain", AppDomain.CurrentDomain.Evidence, setup);
IPlugin plugin = (IPlugin)appDomain.CreateInstanceFromAndUnwrap(assemblyName,                        "Plugin.MyPlugins");

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

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?

最好的问候

5 个答案:

答案 0 :(得分:21)

我想我有答案! 如果您想删除已加载的程序集,则ØyvindSkaar的答案将无效。

而不是

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 :(得分:8)

我知道这个帖子已经死了,但我正在研究这个问题而且我得到了答案(凌晨1点30分......)

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

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:4)

请参阅以下页面:

使用AppDomain AppDomainSetup

设置新的LoaderOptimization.MultiDomainHost

E.g。

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

答案 4 :(得分:3)

我们所做的是拥有一个为程序集监视的文件夹。添加程序集时,应用程序将其复制到临时目录,为其提供唯一的文件名并从中加载。

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

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