Updater — Система обновлений для проектов DevelNext

По мере созданий релизов собственного ПО многие разработчики встречаются с проблемой, когда у пользователей установлена неактуальная версия программы. Для DevelNext годных решений я ещё не видел, поэтому решил написать собственный Updater.

GIF-анимация (демо)

GIF-анимация (wInfo)


Т.к. я за открытое ПО, система обновлений будет завязана на репозитории GitHub (исходники открыты, каждый может переделать под себя), актуальные версии ПО будут искаться и скачиваться с releases указанного репозитория.

Принцип работы такой:

  • 1. Рядом с исполнительным файлом приложения лежит утилита Updater.jar, которая будет отвечать за проверку и установку новых версий.
  • 2. Программа после своего старта запускает Updater.jar, передаёт ему текущую версию и ждёт от него ответа (в фоновом потоке конечно же).
  • 3. Updater проверяет в релизах репозитория github актуальную версию.
  • 4. Если новых версий не найдено — updater закрывается, программа продолжает работу, пользователь никаких лишних сообщений не видит.
  • 5. Если же найдена новая версия, updater спрашивает у пользователя разрешение (без ведома пользователя качать обновы не хорошо), получив добро, закрывает приложение, скачивает файлы с хаба, заменяет их и обратно запускает приложение.
  • Необходимо завершить работу приложения перед обновлением, чтоб updater смог обновить файлы. Для этого updater отправляет сообщение в stdout, его получает приложение и завершает работу.

Итак начинаем, необходимо скачать содержимое этого репозитория github.

Содержимое репозитория:

  • Папка bundle — пакет с необходимым функционалом
  • Папка project-updater — исходники проекта Updater, который отвечает за обновление программы, его необходимо собрать в Updater.jar
  • Папка project-updateMe — исходники демо проекта
  • Папка demo — собственно демонстрация, запускаем UpdateMe.jar

Последовательность действий:
1. Собираем пакет Updater
2. Собираем приложение Updater.jar
3. Собираем наше приложение, которое будет обновляться
4. Выкладываем обновления на GitHub

Собираем пакет

Для этого нужно перейти в папку bundle и выполнить команду:

Для командной строки Windows:

Соответственно вместо path_to_bundle — полный путь к папке bundle

Сборка пакета в командной строке

В папке bundle\build появится готовый пакет dn-updater-bundle.dnbundle, его нужно будет установить в DN.

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

Собираем приложение Updater.jar

Для этого открываем проект из папки project-updater
Из подключенных пакетов должны быть Zip (встроен в DN) и Updater (собранный нами ранее).

Открываем код модуля загрузчик, ищем строку

И меняем имя пользователя и название репозитория на своё. Для работы демо версии можно оставить эти значения.

Меняем внешний вид формы UpdateForm под себя. Собираем проект в jar приложение. На выходе получаем файл Updater.jar

Сборка Updater.jar

Добавляем Updater к своему приложению

(на примере проекта updateMe)

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

Собираем программу. Можно в jar, можно в exe (не важно — portable или нет), но обязательно отметить галочку «объединить все исходники в один исполняемый файл», иначе будут некорректно работать пути в программе, если она запущена от имени администратора. Про это я писал в статье про рабочие директории.

Параметры сборки exe приложения

Рядом с исполняемым файлом нужно скопировать файл Updater.jar. Запускаем, проверяем.

Т.к. обновлений нет, сообщений не видно

Выпускаем обновление

Указываем в проекте новую версию:

Проект с обновлённой программой

Собираем, открываем свой репозиторий, раздел releases, создаём новый релиз с указанием версии, заголовка, описания.

Открыли репозиторий

Новый релиз

Добавляем версию описание, загружаем файлы

Updater поддерживает числовое значение версий, разделённых точкой, например, 1, 1.0, 0.1.2, 1.2.3.4
Если обновление состоит из нескольких файлов, их можно упаковать в zip-архив и он будет распакован в папке с программой.

Проверяем обновление:

Запускаем приложение. Спустя несколько секунд появляется окно с предложением обновиться.


Нажимаем скачать, приложение закрывается, начинается загрузка обновления.


После завершения обновления приложение снова запускается.


Программа успешно обновилась :-) .

p.s. Постарался максимально прокомментировать код. В планах добавить бекап текущей версии перед обновлением, сверку контрольных сумм.

  1. Ничего не работает! Скриншот кода и ошибки внизу.

    Ошибка: https://ibb.co/mEb1GK .

    • TsSaltan:

      В этом проекте нет формы с именем «Updatec», ошибка явно после изменения кода

  2. Аноним:

    нашел баг! если UpdateMe переместить куда — то и запустить Update и согласиться с установкой обн., а потом перекинутый UpdateMe вернуть с снова с заменой обновленной, то при запуске будет требовать обн. если согласиться то текст «подготовка…» будет бесконечна, при этом не обновляясь и не будет удален файл .tmp. Вообщем это ОБХОД ОБНОВЛЕНИЙ!!! Решения есть?

    • lollipop:

      Добрый день, после дейстивй с командой сборки пакета в CMD, командная строка примерно за секунду сама закрывается и файл пакета расширений не создается. Да и папки build изначально нет. Одним словом после последней команды командная строка закрывается и пакет не создается. Может вы собирете пакет для нас, чтобы сильно не мучаться, а добавите его в архив с файлами. ?…

  3. viteq:

    После дейстивий в кмд в build ничего нету
    Пакетов никаких не было(

  4. Аноним:

    Не работает. Запускаю… пишет проверка обновлений потом по сути должна передаваться версия в файл updater.jar но он (updater.jar) даже не открывается. Помогите умоляю

  5. Аноним:

    Здравствуйте, встретился с такой ошибкой — Fatal error: Uncaught ParseError: Syntax error, unexpected ‘;’, expecting ‘:’ in res://app/modules/AppModule.php on line 23, position 61
    Пишет, что-бы поменять ; на : здесь — $currentVersion = $GLOBALS[‘argv’][1] ?? ‘0.0.0.1’;
    Пакет Updater встроен

    • Аноним:

      Самое интересное, что я ничего не менял/трогал, а ошибка присутствует.

      • Аноним:

        Разобрался. Помогло обновление, а я мучался час с попыткой исправить ошибку без обновления:P.
        Не понимаю, почему у меня не автообновлялся DevelNext…
        Если вы не против, то удалите мои комменты, а то чот стыдно…

  6. Алексей:

    Извиняюсь, разобрался

  7. Алексей:

    Чёто ничего не получается… Если значения по умолчанию — программа обновляется, если меняю значения на свои — ничего не происходит. Я закинул архив UpdateMe.zip на github, сменил имя пользователя и название репозитория, указал какой файл скачивать (UpdateMe.zip), экспериментировал с версиями, результат один — не видит обновления. Переменная $check вообще ничего не возвращает…

  8. MWStudio:

    Круто. Встрою в DevelNext MOD по возможности. Ну если ты не против :D

    • TsSaltan:

      Конечно не против. Я ещё не делал пост в группе вк, думал никто не заметит эту статью) Нужно ещё хорошенько протестировать на наличие ошибок.