Я создаю самообновляющееся приложение, в котором большая часть кода хранится в отдельной 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
о, блин, не знал, что у меня нет репутации
Вы, конечно же, ответили здесь на свой вопрос. Если вы обновляете и обновляете общий код, то оба домена приложений заблокируют этот код, поэтому вы не сможете его удалить. Программа обновления не должна пытаться обновить свой собственный код, это не сработает.
Я думаю, что напишу вызовы start и stop в приложении командной строки, чтобы я мог дождаться завершения потоков, вместо того, чтобы убивать процесс для его обновления.
Для этого может быть решение с использованием надстроек MEF или Mono.





Единственный способ, которым я когда-либо управлял чем-то подобным, - это разместить DLL в отдельном домене приложения для сборки, которая пытается ее удалить. Я выгружаю другой домен приложения, а затем удаляю DLL с диска.
Если вы ищете способ выполнить обновление, я бы подумал, что выбрал бы исполняемый файл-заглушку, который порождает настоящий AppDomain. Затем, когда этот исполняемый файл-заглушка обнаруживает, что необходимо применить обновление, он закрывает другой домен приложений, а затем выполняет магию обновления.
Обновлено: программа обновления не может совместно использовать библиотеки DLL с тем, что она обновляет, иначе она заблокирует эти библиотеки DLL и, следовательно, предотвратит их удаление. Я подозреваю, что именно поэтому вы все еще получаете исключение. Средство обновления должно быть автономным и не зависеть ни от чего, что использует другой домен приложений, и наоборот.
Согласен, это единственный известный мне способ сделать это.
Я тоже поддержу это. Многие из новых приложений, которые я использую (Paint.NET, FileZilla), имеют отдельное приложение, запускаемое для выполнения обновления, которое вызывает программу удаления, чтобы удалить приложение, а затем переустановить новое. В вашем случае вы можете удалить DLL, а затем заменить.
Я согласен - здесь мы имеем дело с двумя аспектами.
прикрепление прокси-библиотеки в отдельном домене приложения по-прежнему вызывает исключение при удалении
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_ALLOWEDflag in dwFlags.When moving a directory, the destination must be on the same drive.
If dwFlags specifies
MOVEFILE_DELAY_UNTIL_REBOOTand 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.
вау, это супер непонятно, спасибо. Конечно, было бы то же самое, проверять наличие последней версии при запуске, чем я сейчас занимаюсь.
Почему вы сделали это вики? Тебе следовало взять репутацию. Это хороший вопрос.