Выполнение, а затем удаление DLL в c # - PullRequest
2 голосов
/ 07 октября 2008

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

Как мне создать приложение на 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

Ответы [ 4 ]

6 голосов
/ 07 октября 2008

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

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

РЕДАКТИРОВАТЬ: средство обновления не может делить DLL с тем, что оно обновляет, в противном случае оно заблокирует эти DLL и, следовательно, предотвратит их удаление. Я подозреваю, что именно поэтому вы все еще получаете исключение. Средство обновления должно быть автономным и не зависеть ни от чего, что использует другой домен приложений, и наоборот.

1 голос
/ 29 мая 2009

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

MoveFileEx От MSDN ;

lpNewFileName [in, необязательно ] Новый имя файла или каталога на локальный компьютер.

Когда перемещается файл, место назначения может быть в другой файловой системе или объем. Если пункт назначения включен другой диск, вы должны установить MOVEFILE_COPY_ALLOWED флаг в dwFlags.

При перемещении каталога пункт назначения должен быть на том же диске.

Если dwFlags указывает MOVEFILE_DELAY_UNTIL_REBOOT и lpNewFileName равно NULL , MoveFileEx регистрирует файл lpExistingFileName быть удаленным , когда система перезагружается. Если ссылка lpExistingFileName ссылается в каталог, система удаляет каталог при перезапуске, только если каталог пуст.

1 голос
/ 08 марта 2009

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

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

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

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

1 голос
/ 07 октября 2008

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

...