Подтвердить что ты не робот

Как удалить плагиновую сборку после AppDomain.Unload(домен)

У меня есть странная проблема. я хотел бы удалить сборку (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");

Мне также нужна сборка infos, потому что я не знаю, какие классы в 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);

Как можно получить сборку infos из appDomain без блокировки сборки?

С наилучшими пожеланиями

4b9b3361

Ответ 1

Я думаю, что у меня есть ответ! ответ от Ø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);

С наилучшими пожеланиями

Ответ 2

Я знаю, что эта тема совсем мертва, но я сейчас работаю над этим, и я просто получил ответ (в 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();
}

И это на самом деле не бросает никаких исключений!!! Надеюсь, кто-то прочитает это и что он ответит на вопрос!

Ответ 3

Смотрите эти страницы:

Задайте новый AppDomain AppDomainSetup с помощью LoaderOptimization.MultiDomainHost

например.

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

Что мы делаем, это иметь одну папку, которая просматривается для сборок. Когда сборка добавлена, приложение копирует ее в каталог temp, дает ей уникальное имя файла и загружает его оттуда.

Когда приложение впервые загружено, оно пытается удалить папку temp.

Я не думаю, что это напрямую отвечает на ваш вопрос, но, вероятно, решает вашу проблему.

Ответ 5

Если вы загружаете сборку как поток, она должна работать.

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