Выполнение, а затем удаление DLL в C#

Я создаю самообновляющееся приложение, в котором большая часть кода хранится в отдельной DLL. Это командная строка, которая в конечном итоге будет запущена в Mono. Я просто пытаюсь заставить этот код работать на C# в Windows из командной строки.

Как я могу создать приложение C#, которое я могу удалить поддерживающую dll во время его работы?

AppDomain domain = AppDomain.CreateDomain("MyDomain");
ObjectHandle instance = domain.CreateInstance( "VersionUpdater.Core", "VersionUpdater.Core.VersionInfo");
object unwrap = instance.Unwrap();
Console.WriteLine(((ICommand)unwrap).Run());
AppDomain.Unload(domain);
Console.ReadLine();

на ReadLine VersionUpdater.Core.dll все еще заблокирован от удаления

Интерфейс ICommand находится в VersionUpdater.Common.dll, на который ссылаются как приложение командной строки, так и VersionUpdater.Core.dll

Почему вы сделали это вики? Тебе следовало взять репутацию. Это хороший вопрос.

GEOCHET 07.10.2008 21:16

о, блин, не знал, что у меня нет репутации

Scott Cowan 08.10.2008 12:02

Вы, конечно же, ответили здесь на свой вопрос. Если вы обновляете и обновляете общий код, то оба домена приложений заблокируют этот код, поэтому вы не сможете его удалить. Программа обновления не должна пытаться обновить свой собственный код, это не сработает.

Jeff Yates 08.10.2008 18:45

Я думаю, что напишу вызовы start и stop в приложении командной строки, чтобы я мог дождаться завершения потоков, вместо того, чтобы убивать процесс для его обновления.

Scott Cowan 08.10.2008 20:14

Для этого может быть решение с использованием надстроек MEF или Mono.

Scott Cowan 01.06.2009 19:19
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
2 629
4

Ответы 4

Единственный способ, которым я когда-либо управлял чем-то подобным, - это разместить DLL в отдельном домене приложения для сборки, которая пытается ее удалить. Я выгружаю другой домен приложения, а затем удаляю DLL с диска.

Если вы ищете способ выполнить обновление, я бы подумал, что выбрал бы исполняемый файл-заглушку, который порождает настоящий AppDomain. Затем, когда этот исполняемый файл-заглушка обнаруживает, что необходимо применить обновление, он закрывает другой домен приложений, а затем выполняет магию обновления.

Обновлено: программа обновления не может совместно использовать библиотеки DLL с тем, что она обновляет, иначе она заблокирует эти библиотеки DLL и, следовательно, предотвратит их удаление. Я подозреваю, что именно поэтому вы все еще получаете исключение. Средство обновления должно быть автономным и не зависеть ни от чего, что использует другой домен приложений, и наоборот.

Согласен, это единственный известный мне способ сделать это.

GEOCHET 07.10.2008 21:16

Я тоже поддержу это. Многие из новых приложений, которые я использую (Paint.NET, FileZilla), имеют отдельное приложение, запускаемое для выполнения обновления, которое вызывает программу удаления, чтобы удалить приложение, а затем переустановить новое. В вашем случае вы можете удалить DLL, а затем заменить.

Dillie-O 07.10.2008 21:17

Я согласен - здесь мы имеем дело с двумя аспектами.

Saif Khan 07.10.2008 21:37

прикрепление прокси-библиотеки в отдельном домене приложения по-прежнему вызывает исключение при удалении

Scott Cowan 08.10.2008 12:37

Unwrap загрузит сборку типа объекта в вызывающий его домен приложения. Один из способов обойти это - создать тип в вашей «базовой» сборке, который вызывает command.run, а затем загрузить его в новый домен приложения. Таким образом, вам никогда не придется вызывать развертывание объекта из типа в другой сборке, и вы можете удалить сборку на диске.

Когда я создавал самообновляющееся приложение, я использовал идею заглушки, но заглушкой было само приложение.

Приложение запускалось, ищи обновления. Если он обнаружит обновление, он загрузит копию нового приложения во временное хранилище, а затем запустит его (System.Diagnostics.Process.Start ()), используя параметр командной строки, в котором указано «вы обновляетесь». Затем оригинальный exe завершается.

Созданный exe запускается, видит, что это обновление, и копирует себя в исходный каталог приложения. Затем он запускает приложение из этого нового места. Затем порожденный exe заканчивается.

Вновь запущенный exe из исходного места установки приложения запускается - видит временный файл и удаляет его. Затем возобновляет нормальное выполнение.

Вы всегда можете использовать MOVEFILE_DELAY_UNTIL_REBOOT для удаления при перезагрузке. Скорее всего, это наименее хакерский способ делать подобные вещи, я обычно вижу такие вещи, как хоккей; загрузка новых DLL или инъекция в explorer.exe, даже исправление системной dll для загрузки в другой процесс и т. д.

MoveFileExИз MSDN;

lpNewFileName [in, optional] The new name of the file or directory on the local computer.

When moving a file, the destination can be on a different file system or volume. If the destination is on another drive, you must set the MOVEFILE_COPY_ALLOWED flag in dwFlags.

When moving a directory, the destination must be on the same drive.

If dwFlags specifies MOVEFILE_DELAY_UNTIL_REBOOT and lpNewFileName is NULL, MoveFileEx registers the lpExistingFileName file to be deleted when the system restarts. If lpExistingFileName refers to a directory, the system removes the directory at restart only if the directory is empty.

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

Scott Cowan 01.06.2009 19:15

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