Лучший метод для реализации самообновляющегося программного обеспечения - PullRequest
11 голосов
/ 31 июля 2009

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

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

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

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

Ответы [ 6 ]

8 голосов
/ 31 июля 2009

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

Запустите Update.exe и дайте ему сделать это:

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

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

7 голосов
/ 31 июля 2009

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

6 голосов
/ 31 июля 2009

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

3 голосов
/ 31 июля 2009

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

Единственная причина A состояла в том, чтобы запустить B. Таким образом, когда B («реальное» приложение) загрузило обновление, оно смогло заменить A в случае необходимости.

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

1 голос
/ 31 июля 2009

То, как мы делаем это с нашим собственным приложением:

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

  1. Отображаются уведомления о простоях / крайние сроки.
  2. средство обновления выполняет проверку обновления.
  3. Обновления загружены и установлены.
  4. Приложение запущено.
  5. Приложение выполняет обновление программы обновления (проверяет наличие файла Updater.fp7.gz в папке / update)

Редактировать: К сожалению, пропущенный шаг 5.

0 голосов
/ 25 апреля 2012

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

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

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

...