Обновления программы - QualitySolution/QSProjects GitHub Wiki
Модуль обновлений приложения состоит из двух частей:
- проверка и установка обновлений приложения;
- координация процесса через
VersionCheckerService.
Для обновления приложения сейчас используется связка IAppUpdater + VersionCheckerService.
Если вашему проекту нужно обновлять еще и базу данных, используйте отдельную статью: Обновление базы данных.
Минимальная настройка модуля (только обновление приложения)
Ниже приведен актуальный минимальный набор регистраций в Autofac.
#region Gtk UI
builder.RegisterType<GtkGuiDispatcher>().As<IGuiDispatcher>();
builder.RegisterType<GtkWindowsNavigationManager>()
.AsSelf()
.As<INavigationManager>()
.SingleInstance();
#endregion
#region База
builder.Register(c => QSProjectsLib.QSMain.ConnectionStringBuilder).AsSelf();
builder.Register(c => new MySqlConnectionFactory(Connection.ConnectionString)).As<IConnectionFactory>();
builder.Register(c => c.Resolve<IConnectionFactory>().OpenConnection())
.As<DbConnection>()
.InstancePerLifetimeScope();
builder.RegisterType<ParametersService>().AsSelf();
#endregion
#region Версии и обновления
builder.RegisterType<ApplicationVersionInfo>().As<IApplicationInfo>();
builder.RegisterModule(new UpdaterDesktopAutofacModule());
builder.RegisterModule(new UpdaterAppAutofacModule());
#endregion
Что регистрируют модули:
UpdaterDesktopAutofacModule—CheckBaseVersionиVersionCheckerService;UpdaterAppAutofacModule—IAppUpdater,ReleasesService,ISkipVersionState,NewVersionViewModel;
Если проекту нужно обновлять базу данных
Для сценариев с миграциями базы используйте отдельную статью: Обновление базы данных.
В этой статье описывается только общий чекер обновлений приложения.
Автоматическая проверка обновлений при старте
Актуальный способ — получить VersionCheckerService из DI и вызвать RunUpdate():
using(var scope = MainClass.AppDIContainer.BeginLifetimeScope()) {
var checker = scope.Resolve<VersionCheckerService>();
UpdateInfo? updateInfo = checker.RunUpdate();
if(updateInfo?.Status == UpdateStatus.AppUpdateIsRunning) {
quitService.Quit();
return;
}
if(updateInfo?.Status == UpdateStatus.ConnectionError) {
logger.Warn(updateInfo.Value.Message);
}
if(updateInfo?.Status == UpdateStatus.BaseError) {
interactive.ShowMessage(updateInfo.Value.ImportanceLevel, updateInfo.Value.Message, updateInfo.Value.Title);
quitService.Quit();
return;
}
if(updateInfo?.Status == UpdateStatus.ExternalError) {
interactive.ShowMessage(updateInfo.Value.ImportanceLevel, updateInfo.Value.Message, updateInfo.Value.Title);
quitService.Quit();
return;
}
}
Именно этот сценарий рекомендуется вызывать при старте главного окна.
Что делает VersionCheckerService.RunUpdate()
Сервис объединяет несколько шагов:
- проверяет совместимость версии приложения и базы через
CheckBaseVersion; - если подключен
IAppUpdater, вызываетCheckUpdate(); - если доступно обновление приложения, показывает окно через
IAppUpdater.RunUpdate(); - возвращает
UpdateInfo?со статусом результата.
Если в проекте подключен модуль обновления БД, VersionCheckerService также сможет координировать этот шаг. Подробности и настройка — в Обновление базы данных.
Поэтому для автоматического сценария лучше использовать именно VersionCheckerService, а не напрямую IAppUpdater.
Ручная проверка обновлений по кнопке или пункту меню
Для ручной проверки теперь нужно использовать IAppUpdater в два шага:
using(var scope = MainClass.AppDIContainer.BeginLifetimeScope()) {
var updater = scope.Resolve<IAppUpdater>();
updater.CheckUpdate();
updater.RunUpdate();
}
Это важно:
CheckUpdate()только получает информацию о доступных релизах;RunUpdate()показывает окно новой версии или сообщение, что обновлений нет / произошла ошибка;- параметра
manualRunуCheckUpdate()больше нет.
Если вызвать только RunUpdate() без предварительного CheckUpdate(), у обновлятора не будет актуальных результатов проверки.
Каналы обновлений
В модуле приложения поддерживаются каналы:
UpdateChannel.Current— текущий;UpdateChannel.Stable— стабильный;UpdateChannel.Off— не проверять обновления автоматически.
Значение хранится в конфигурации по ключу:
AppUpdater:Channel
Если выбран UpdateChannel.Off, то ApplicationUpdater.CheckUpdate() не обращается к серверу обновлений и возвращает информационный результат.
Отключить автоматическую проверку можно, например, так:
configuration["AppUpdater:Channel"] = nameof(UpdateChannel.Off);
Так же это делает NewVersionViewModel.OffAutoUpdate() из окна новой версии.
Пропуск версии
Состояние пропущенной версии хранится через ISkipVersionState.
- при ручном пропуске в окне новой версии вызывается
SkipVersion(); - при следующем автозапуске
VersionCheckerServiceучитывает это состояние; - если версия базы уже новее, чем установленная версия приложения, пропуск может быть проигнорирован, чтобы не оставить приложение несовместимым с базой.
Точки входа
Актуальные точки входа:
- автоматическая проверка —
VersionCheckerService.RunUpdate(); - ручная проверка —
IAppUpdater.CheckUpdate()+IAppUpdater.RunUpdate().