у меня странная проблема. Я хочу удалить сборку (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);
Как можно получить информацию о сборке из домена приложения без блокировки сборки?
наилучшие пожелания





Что мы делаем, так это чтобы одна папка отслеживалась на предмет сборок. Когда сборка добавляется, приложение копирует ее во временный каталог, дает ей уникальное имя файла и загружает его оттуда.
Когда приложение загружается впервые, оно пытается очистить временный каталог.
Я не думаю, что это прямо отвечает на ваш вопрос, но, вероятно, это решит вашу проблему.
Если вы загрузите сборку как поток, она должна работать.
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);
наилучшие пожелания
Когда я попробовал, он работал нормально, но ваш все равно короче;)
Есть много похожих вопросов о выгрузке DLL и использовании отдельных доменов приложений, но они, похоже, не работают, когда вы действительно хотите Удалить DLL. Это определенно работает независимо от того :)
Хороший! Не нужен даже другой домен приложения.
это не сработает, если вы используете другой домен приложения, но это определенно лучший подход, чем усложнение с помощью домена приложения :)
Мне непонятно, как выгружается .dll, если выгружаются только домены приложений. Решение, использующее массив байтов, похоже, не использует какой-либо домен приложений. Может кто-нибудь уточнить?
Меня интересует файл .config.
Я знаю, что эта ветка совсем мертва, но в настоящее время я работаю над этим и только что получил ответ (в 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/…)
Смотрите эти страницы:
Установите новый 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",
}
);
это должно быть, но это не так. :( UnauthorizedAccessException в File.Delete (путь);