Как мне реализовать автообновление? - PullRequest
62 голосов
/ 24 октября 2008

Многие программы включают автообновление, при котором программа периодически просматривает обновления, а затем загружает и применяет любые найденные обновления. Исправлены ошибки в программе, изменены файлы поддержки, и (как правило) все сделано лучше.

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

Кажется, довольно легко внедрить систему, которая ищет обновления в сети и загружает их, если они доступны. Эта часть автообновления будет существенно меняться от реализации к реализации. Вопрос в том, каковы различные подходы применения патчей. Просто скачиваете файлы и заменяете старые на новые, запускаете скачанный скрипт миграции, монтируете исправления частей системы и т. Д.? Концепции являются предпочтительными, но приветствуются примеры на Java, C, Python, Ruby, Lisp и т. Д.

Ответы [ 16 ]

48 голосов
/ 24 октября 2008

Я думаю, что «языковая независимость» будет здесь ограничивающим фактором. Приложения имеют так много форм и размеров, что не существует единого решения для всех. Я реализовал несколько автообновлений на нескольких языках, и никакие два не были похожи.

Самая общая философия заключается в том, что приложение проверяет с некоторым домашним местоположением (веб-адрес, веб-запрос, местоположение корпоративной сети и т. Д.), Чтобы либо спросить, является ли его версия текущей, либо спросить, какая самая последняя версия. Если ответ требует обновления, этот процесс будет отличаться для каждой ситуации.

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

Возможно, мы поможем вам лучше, если вы сузите параметры.

ОБНОВЛЕНИЕ: подход к «исправлению» также зависит от характера приложения, и здесь очень большое разнообразие. Например, если у вас есть один исполняемый файл, то, вероятно, наиболее целесообразно заменить исполняемый файл. Если в вашем приложении много файлов, вы должны искать способы минимизировать количество заменяемых файлов. Если ваше приложение сильно настроено или параметризовано, вы должны стремиться минимизировать усилия по адаптации. Если ваше приложение использует интерпретированный код (например, приложение Excel VBA или приложение MS Access MDB), вы можете заменить части кода. В приложении Java вам может понадобиться только заменить файл JAR или даже подмножество содержимого JAR. Вам также потребуется способ узнать текущую версию клиента и соответствующим образом обновить ее. Я мог бы продолжать и продолжать, но я надеюсь, что вы видите мою точку зрения о разнообразии. Это один из тех случаев, когда лучший ответ обычно начинается с «Ну, это зависит ...!» Вот почему так много ответов включают «Пожалуйста, сузьте параметры».

18 голосов
/ 28 января 2009

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

Доверяете ли вы источнику загрузки? Возможно, вы звоните домой, чтобы получить обновление, но что, если в середине есть человек, который перенаправляет на вредоносный сервер. HTTPS или подобное безопасное соединение поможет, но рекомендуется дважды проверять биты, которые вы в конечном итоге загружаете с помощью проверки цифровой подписи.

8 голосов
/ 04 декабря 2008

Сначала вам нужен файл на домашней странице вашего приложения с последней версией. Лучше всего, я думаю, иметь специальную таблицу SQL для этой задачи и заполнять ее автоматически после публикации новой версии / завершения ночной сборки. Ваше приложение создает новый поток, который запрашивает встроенную ссылку http с версией и сравнивает с текущей. В .NET использовать можно использовать такой код:

Version GetLatestVersion() {
HttpWebRequestrequest = (HttpWebRequest)WebRequest.Create(new Uri(new Uri(http://example.net), "version.txt));
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (request.HaveResponse)
{
  StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.Default);
  return new Version(stream.ReadLine());
}
else
{
  return null;
}
}

Version latest = GetLatestVersion();
Version current = new Version(Application.ProductVersion);
if (current < latest)
{
  // you need an update
}
else
{
  // you are up-to-date
}

В этом примере version.php только в одной простой строке, такой как 1.0.1.0.

Еще один совет, который я могу дать - как скачать обновление. Мне очень нравится следующая идея: в ресурсах вашего приложения есть строка CLR-кода, которую вы на лету компилируете (используя CodeDom) во временную папку, главное приложение вызывает ее и закрывает. Программа обновления считывает аргументы, настройки или реестр и загружает новые модули. И вызывает основное приложение, которое удаляет все временные файлы. Готово! * * 1006

(но здесь все о .NET)

5 голосов
/ 28 января 2009

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

Кроме того, в Windows вы не можете удалить исполняемый файл, который используется, поэтому вы, вероятно, захотите удалить небольшой исполняемый файл в папку Temp, которая запускает весь процесс, а затем удалить его в конце из экземпляра новая версия, которая была запущена (или просто зарегистрируйте ее для удаления при следующей перезагрузке ).

2 голосов
/ 30 января 2009

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

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

Было бы намного лучше, если бы автообновление просто запрашивало учетные данные администратора при необходимости и продолжало с этим.

2 голосов
/ 28 января 2009

Это не столько полный ответ, сколько пример механизма автоматического обновления, который я недавно реализовал. Ситуация немного отличается от традиционного пользовательского приложения типа Firefox, поскольку оно было внутренним инструментом, используемым на работе.

По сути, это небольшой скрипт, который управляет очередью ветвей Subversion, которая будет собрана и упакована в установщик. Он читает небольшой файл, в который записываются имена ветвей, берет первый, перезаписывает его в конце файла и запускает процесс сборки, который включает в себя вызов нескольких скриптов. Конфигурация для каждой создаваемой ветви записывается в файле .INI, который хранится в хранилище Subversion вместе с самим инструментом.

Поскольку этот инструмент работает на нескольких компьютерах, я хотел, чтобы он автоматически обновлялся на всех компьютерах, как только я внес изменение в сам инструмент или в сценарии конфигурации.

Способ, которым я это реализовал, был прост: когда я запускаю инструмент, он становится «внешней оболочкой». Эта внешняя оболочка делает 2 очень простых вещи:

  • svn update на себя и на файлы конфигурации
  • запускается снова, на этот раз как «внутренняя оболочка», которая фактически обрабатывает одну конфигурацию (а затем снова выходит).

Эта очень простая система обновления "сам в цикле" уже несколько месяцев хорошо нам помогает. Это очень элегантно, потому что оно автономно: автообновление - это сама программа. Поскольку «внешняя оболочка» (часть автообновления) очень проста, не имеет значения, что она не получает выгоду от обновлений как «внутренняя оболочка» (которая выполняется каждый раз из обновленного исходного файла).

2 голосов
/ 24 октября 2008

Самый простой подход - запросить у вашей программы сервер (веб-сайт), чтобы узнать, есть ли обновление. Если есть обновление, вы можете отобразить сообщение пользователю, которое предложит ему загрузить более новую версию и предоставит ссылку.

Альтернативным и более сложным решением было бы создание небольшой службы Windows (или демона Unix), которая периодически проверяет наличие обновлений, эта служба может загрузить обновление и запустить установщик.

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

1 голос
/ 28 января 2009

Поскольку автоматическое обновление является распространенным сценарием, для большинства языков доступен как минимум один пакет, поддерживающий это. (Ниже я перечислю некоторые из доступных пакетов)

Одной из действительно хороших идей является дистрибутив ClickOnce для .NET, это инсталлятор, который помещает в песочницу ваше приложение и устанавливается в контексте пользователя, поэтому никаких прав администратора не требуется. Вы можете настроить ClickOnce в своей публикации, чтобы проверять наличие обновлений при каждом запуске приложения.

Java имеет Java Web Start , которая предлагает те же функции для Java-апплетов.

В Delphi есть множество статей об автообновлении, в Torry есть список компонентов WebUpdate , например GoUpdater , похоже, обладает очень широким спектром функциональных возможностей.

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

0 голосов
/ 27 ноября 2018

Если ваше программное обеспечение с открытым исходным кодом и ориентировано на Linux или разработчиков. Интересно установить ваше программное обеспечение в виде git-репо. И когда он запускает стабильную ветку время от времени или каждый раз при запуске.

Это особенно легко, когда ваше приложение управляется через npm, sbt, mavan, stack, elm-package или другие.

0 голосов
/ 28 апреля 2015

Вы можете использовать мое решение (часть проекта Target Eye ). http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto

...