Лучший способ реализации самообновляющегося программного обеспечения

У нас есть минимальная "updater" exe, которая проверяет удаленный URL-адрес для обновлений, загружает их и заменяет файлы на диске до запуска реального приложения. Однако, если мы хотим заменить updater EXE, то AFAIK у нас есть два варианта:

1) Теневые копии ассемблирования, в результате чего .Net создаст теневую копию EXE (и любых ссылочных ассемблеров) и загрузит эти сборки, например что не теневые сборки могут быть заменены и будут использоваться, когда приложение будет запущено.

2) Определите, какие файлы заменены и переименовать/переместить их на диск. Windows, похоже, позволяет переименовывать/перемещать заблокированные файлы, поэтому мы можем перемещать файлы и копировать их в новых сборках. Опять же, при следующем запуске приложения мы будем запускать новые сборки. Этот подход упоминается здесь

Является ли этот второй метод рекомендуемым? Есть ли подводные камни для этого подхода?

Ответ 1

Как насчет ClickOnce развертывание?

Ответ 2

Im использует второй метод без каких-либо проблем. Просто убедитесь, что загруженная сборка была загружена правильно.;)

Запустите Update.exe и позвольте ему сделать это:
1. загрузите новый файл update.exe как update.ex_
2. переименуйте update.exe в update.bak(вы можете переименовать его, но не перезаписать)
3. переименуйте update.ex_ в update.exe
4. перезапустите update.exe

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

Ответ 3

Другой вариант: когда основное приложение хочет обновить себя, оно запускает новый процесс обновления и затем закрывается. Тем временем созданный процесс ожидает закрытия основного приложения (процесс исчезнет), а затем обновит все необходимые файлы (в том числе .exe). После этого он просто перезапускает основное приложение и выходит из процесса обновления.

Ответ 4

В проекте, над которым я работал, есть 2 исполняемых файла. Позвольте называть их A и B.

Единственная причина существования A заключалась в том, чтобы начать B. Итак, когда B ( "реальное" приложение) загрузило обновление, оно смогло заменить A, если это необходимо.

Если приложение было перезапущено (через A), A проверил, загрузил ли B некоторые файлы и заменил их до того, как он запустил B.

Ответ 5

Как мы это делаем с нашим внутренним приложением:

Ярлык приложения указывает на обновление.

  • Отображаются сообщения о времени простоя/сроки.
  • программа обновления выполняет проверку обновлений.
  • Обновления загружаются и устанавливаются.
  • Запускается приложение.
  • Приложение выполняет обновление обновления (проверяет наличие Updater.fp7.gz в папке /update )

Изменить: Oops - пропущенный шаг 5.

Ответ 6

Я в основном согласен с Stefan Answer, за исключением того, что он может не работать, если вы хотите правильно работать с UAC в Windows Vista или Windows 7, и ваше приложение правильно установлено в папке Program Files или требуется установить другие зависимости, требующие повышенных разрешений.

В этом случае вы выполняете установку/патч на основе msi или устанавливаете службу Windows, которая работает с необходимой безопасностью, чтобы перезаписать файлы в папке Program Files.

Другим вариантом, если ваше приложение является интерактивным, - это сделать так, как предлагает Игорь Брейц, и создать новый процесс, который делает обновление, которое дает вашему приложению возможность запрашивать повышение разрешений во время обновления. Использование параметра патча или службы Windows, как упоминалось выше, обеспечит лучший пользовательский опыт независимо от сценария (интерактивный/неинтерактивный).