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

у меня странная проблема. Я хочу удалить сборку (plugin.dll на жестком диске), которая уже загружена, но сборка заблокирована операционной системой (перспектива), даже если я ее выгрузил.

например

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

Как можно получить информацию о сборке из домена приложения без блокировки сборки?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
17
0
8 824
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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);

это должно быть, но это не так. :( UnauthorizedAccessException в File.Delete (путь);

Ase 12.01.2009 13:30

Можете ли вы удалить файл, если сначала не загрузите сборку?

Øyvind Skaar 12.01.2009 21:12
Ответ принят как подходящий

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

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

Когда я попробовал, он работал нормально, но ваш все равно короче;)

Øyvind Skaar 12.01.2009 21:13

Есть много похожих вопросов о выгрузке DLL и использовании отдельных доменов приложений, но они, похоже, не работают, когда вы действительно хотите Удалить DLL. Это определенно работает независимо от того :)

Jedidja 25.07.2013 22:59

Хороший! Не нужен даже другой домен приложения.

Thomas Eyde 18.08.2015 13:03

это не сработает, если вы используете другой домен приложения, но это определенно лучший подход, чем усложнение с помощью домена приложения :)

am05mhz 13.01.2016 05:18

Мне непонятно, как выгружается .dll, если выгружаются только домены приложений. Решение, использующее массив байтов, похоже, не использует какой-либо домен приложений. Может кто-нибудь уточнить?

James M 13.11.2016 03:42

Меня интересует файл .config.

Yola 26.03.2021 20:47

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

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

Это правильно. Это должно сработать. Причина, по которой другой способ не работает, заключается в следующем: когда вы вызываете app.Load(), сборка загружается в домен приложения app, а также в домен приложения, в котором выполняется код. После выгрузки app сборка по-прежнему загружается в другом домене приложения. Использование app.DoCallBack приводит к тому, что код запускается в app и, таким образом, сборка загружается только в app. (источники: msdn.microsoft.com/en-us/library/36az8x58.aspx и msdn.microsoft.com/en-us/library/…)

Matthijs Wessels 14.12.2011 02:37

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

Установите новый 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",
    }
);

Другие вопросы по теме