Форум программистов, компьютерный форум, киберфорум
Rius
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Велосипедим обновлятор

Запись от Rius размещена 26.04.2020 в 22:34
Показов 4324 Комментарии 2

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

Безотносительно языка программирования.

Заранее, прежде чем приступать к кодингу, должно быть решено несколько вопросов:
  1. В каком виде поставлять обновления?
  2. Как проверять, что существует новая версия?
  3. Когда проверять, что существует новая версия?
  4. Когда начинать загрузку?
  5. Как загружать?
  6. Когда устанавливать?
  7. Как устанавливать?
  8. Что делать с данными?

В каком виде поставлять обновление?
  • Если программа из нескольких файлов (dll и прочие ресурсы), то
    • Либо архив, тогда также же в программе должна быть встроена функциональность распаковки/удаления/замены файлов;
    • Либо инсталлятор, который это всё автоматом берёт на себя;
  • Если программа из одного EXE, можно поставлять его. Но тогда в программе должны быть предусмотрены некоторые дополнительные функции (см. ниже);
  • Если файлов достаточно много (клиент какой-либо игры на фришарде), лучше всего посмотреть через сниффер, как этот вопрос решают существующие клиенты игр (типа EVE Online, Elite Dangerous, WoT и др.).
    Так как в этом случае может быть оптимальнее загружать только отличающиеся файлы, а то и вовсе лишь сами отличия (патчи).
    Пример по ссылке в конце ↓↓↓

Как проверять, что существует новая версия?
В первую очередь, программа должна иметь при себе собственный идентификатор версии ПО.
Хеш или контрольная сумма файлов программы не годятся, т.к. позволяют только определить только сам факт отличия, а не сравнить, где (здесь или там) версия новее.
Это может быть либо номер версии (172 или 1.0.0.8), либо дата (2020-04-28T23:45:00), либо что-то ещё, позволяющее программе сравнить две версии и однозначно определить, какая из них новее.
Если у вас такого нет вообще, стоит рассмотреть применение, например, Семантического Версионирования.

Далее, программа должна уметь запрашивать данные о доступных обновлениях у поставщика обновлений, а поставщик должен уметь эти данные предоставлять.
В случае применения простого сетевого диска в локальной сети, можно расположить текстовый (json, xml) файлы с необходимыми данными.
В случае своего сервера также можно просто выложить файл (FTP), либо реализовать Web API (на shared хостинге, VPS).

Файл данных должен содержать необходимую для обновления информацию, в частности идентификатор версии ПО и url файла обновления.
Реомендуется предусмотреть хеш файла, с целью проверки его корректности после загрузки.
Также можно добавить дата выпуска, список отличий от предыдущей версии, хеш ревизии и дату коммита Git, и пр.
С сервера, для выложенной на нём актуальной версии программы, требуется получить идентификатор версии ПО.
Пример, как может выглядеть файл в простом случае:
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "Items": [
    {
      "Uri": "https://www.cyberforum.ru/updates/program_1.0.0.exe",
      "FileVersion": "1.0.0.0",
      "ProductVersion": "1.0.0+Branch.master.Sha.bed8da0d56ea48c5e580e3e557f81360c0405431",
      "SHA1": "W/+KW9hRW7pmU5EpB064psKLjHs=",
      "Changes": [
        "Первый выпуск"
      ]
    },
    {
      "Uri": "https://www.cyberforum.ru/updates/program_1.1.0.exe",
      "FileVersion": "1.1.0.0",
      "ProductVersion": "1.1.0+Branch.master.Sha.12adef0d56ea48c5e580e3e557f81360c0405431",
      "SHA1": "W/+459hRW7pmU5E1B064psKLjHs=",
      "Changes": [
        "Исправлены старые баги",
        "Добавлены новые баги"
      ]
    }
  ]
}
Программа просматривает такой файл и выясняет, есть ли версия новее, где её скачать, и о чём стоит сообщить пользователю.

Когда проверять, что существует новая версия?
Встречаются такие варианты:
  • Явным вызовом в меню программы Справка - Проверить наличие обновлений;
  • Автоматически при запуске программы;
  • Перидически в ходе работы программы;
  • Через планировщик заданий Windows (хотя, зачем?).
Иногда при установке программы разработчик предлагает опцию "Проверять обновления автоматически". В зависимости от выбора пользователя далее работает либо ручная проверка, либо автоматическая.

Когда начинать загрузку?
  • Обычно загрузка предлагается после успешной проверки наличия новой версии;
  • Некоторые программы загружают обновление сами, в фоне;
  • Иногда стоит спрашивать о необходимости загрузки. Например, если пакет обновления большой или установка сложна;
  • При показе запроса о начале загрузки, пользователю может быть предоставлена опция отложить установку на некоторое время, в том числе и вовсе отменить (пропустить) обновление.

Как загружать?
  • Некоторые программы выдают ссылку на сайт и предлагают пользователю скачать обновление самостоятельно;
  • Другие приостанавливают работу и в модальном окне показывают ход загрузки файлов;
  • Третьи показывают прогресс где-то в статусбаре, либо вообще не показывают.
Сама загрузка обычно не представляет проблемы, благодаря использованию средств фреймворка и библиотек.
Разве что своего сайта нет и файлы лежат на каком-нибудь облачном хранилище, откуда скачать что-либо можно, только если зайти самостоятельно и кликнуть куда-нибудь. В этом случае следует просто выдать пользователю ссылку на сайт, либо открыть его в браузере.

Когда устанавливать?
Обычно после загрузки сообщается о готовости к установке и предлагается установить обновления. Встречающиеся варианты:
  • Закрыть программу и начать установку.
  • Дождаться закрытия программы и начать установку.
Закрывать программу без разрешения пользователя не принято.

Как устанавливать?
Если используется инсталлятор, достаточно запустить его и сразу закрыть программу.
Исполняемые файлы программы под Windows обычно не могут быть удалены, если они запущены. Там всё не просто, но обходные пути не нужны, т.к. уже давно придумано простое решение. →
Поэтому инсталлятор должен дождаться завершения программы, и лишь потом начать установку. Сделать это можно, например, применением Mutex'а. В частности, такая опция есть у Inno Setup. Инсталлятор пытается создать локальный и/или глобальный Mutex, который также создаёт и программа. А Mutex, как известно, может быть создан только один, в пределах сессии или глобально (см. CreateMutexA function (synchapi.h)).
Тот же инсталлятор в ходе установки определит каталог текущей версии, удалит её, и установит новую. И запустит приложение.

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

Если автор - ССЗБ и вместо инсталлятора (или иной, более полезной функциональности программы) гордо возится с единым exe, то единственно что в предыдущей (архив) последовательности упрощается - распаковка одного файла вместо нескольких. Всё.

Также, есть вариант установить новую версию рядом с существующей, без её удаления. Программа при запуске проверит наличие рядом более новой версии и при обнаружении запустит её, после чего сама закроется. При обнаружении же рядом прежней версии её можно будет удалить.

Что делать с данными?
  • Если программа не имеет никаких сохраняемых данных, то и проблемы нет.
  • Если есть, но их формат никак не меняется от версии к версии, то достаточно их хранить в каталоге пользовательских данных или реестре. Т.е. не в каталоге программы.
  • Если же формат меняется, требуется предусмотреть, что делать при запуске новой версии программы со старыми данными, либо старой программы с новыми данными (если надо откатиться на предыдущую версию ПО). Но хранить их также рекомендуется отдельно.
  • В случае использования базы данных всё гораздо сложнее. Если тема незнакомая, стоит почитать, например, Версионная миграция структуры базы данных: основные подходы.

Примеры:
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 2
Комментарии
  1. Старый комментарий
    опциональная возможность отката на предыдущую версию., включая умный откат данных.
    а так же что то типа цифровой подписи источника обновления.....
    Запись от voral размещена 27.04.2020 в 11:55 voral вне форума
  2. Старый комментарий
    Аватар для SatanaXIII
    Отличная статья. Все описано, что нужно, даже добавить нечего.
    Запись от SatanaXIII размещена 17.03.2023 в 08:49 SatanaXIII вне форума
 
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru