Как мне реализовать автоматическое обновление?

StackOverflow https://stackoverflow.com/questions/232347

  •  04-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

Сначала вам нужен файл на домашнем веб-сайте приложения с последней версией. Лучше всего, я думаю, иметь специальную таблицу 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) во временную папку, главное приложение вызывает ее и закрывает. Программа обновления считывает аргументы, настройки или реестр и загружает новые модули. И вызывает основное приложение, которое удаляет все временные файлы. Готово!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

В настройке Java-Webstart вы запускаете файл JNLP, который затем запускает загрузку файлов Jar, необходимых для запуска приложения.Каждый раз веб-запуск проверяет наличие новых версий Jars и загружает их, заменяя локально кэшированные.С помощью инструмента jardiff вы будете создавать различия только в отношении новых jar-файлов и распространять их через сервер (например,только получить обновление).

Плюсы:

  • всегда в курсе

Минусы:

  • вам нужен сервер приложений (tomcat, JBoss) для распространения файлов
  • вам нужно подключение к Интернету, чтобы получить приложение

Чтение ответа Карла Селеборга дало мне несколько идей о том, как может быть полезен универсальный репозиторий кода.

svn поставляется с инструментом svnsync, который ведет себя как экспорт svn, но отслеживает реальную ревизию, в которой находится ваш экспорт.

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

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

Функция установки исправления в программу - одна из основных функций установщика. Программное обеспечение установщика задокументировано во многих местах, но обычно для каждого установщика: там установщик Microsoft (с установкой расширений Shield), рубиновые камни , файлы Java .jar , различные системы диспетчера пакетов Linux ( RPM , Apt-get ) и другие.

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

Вы можете написать внутренний модуль вашего приложения для выполнения обновлений. Вы можете написать внешнее мини-приложение для выполнения обновлений.

Также обратите внимание на технологию компиляции .NET на лету, которая позволяет создавать такие мини-приложения на лету по требованию. Например, http://fly.sf.net/

Я собираюсь принять ответ для Windows.

Этот способ, кажется, работает хорошо.

В установщике выполните:
1. Создайте службу ручного запуска, которая запускается как LocalSystem, и при запуске обновление останавливается.
2. Измените разрешения службы, чтобы все пользователи могли запускать службу (если все пользователи должны иметь возможность обновлять без прав администратора).
3. Измените основную программу, чтобы проверить наличие обновлений при запуске с использованием простого механизма. Если оно обнаружит обновление, подскажите, хочет ли пользователь его применить.
4. Если пользователь принимает обновление, запустите службу.

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

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

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

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

Если вы ищете кроссплатформенное решение для обновления программного обеспечения, взгляните на www.updatenode.com

Некоторые моменты:

  • бесплатно для проектов с открытым исходным кодом
  • кроссплатформенный клиентский инструмент обновления с открытым исходным кодом
  • уже локализован для самых важных языков
  • легко интегрируется и прост в обращении
  • облачная платформа управления для определения обновлений и управления ими
  • обеспечивает дополнительную поддержку отображения сообщений (информирование о новых событиях, продуктах и ​​т. д.)
  • веб-интерфейс открыт (с помощью сервиса можно создать свой клиент)
  • множество статистических данных об использовании, таких как используемые операционные системы, географическое местоположение, использование версий и т. д.
  • Android API для обновлений мобильных приложений

Просто попробуйте.

Кстати, я являюсь частью команды разработчиков клиента с открытым исходным кодом.:)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top