62 lines
3.3 KiB
C++
62 lines
3.3 KiB
C++
#pragma once
|
||
#include <QObject>
|
||
#include <QString>
|
||
|
||
class QNetworkAccessManager;
|
||
|
||
// Сервис ручной проверки и установки обновлений (Windows). Живёт в собственном
|
||
// QThread, как NetworkService. Полный цикл: GET манифеста → сравнение версий →
|
||
// скачивание zip → проверка sha256 → распаковка → запуск распакованного
|
||
// ARC.exe в режиме --apply-update → выход приложения (UI делает qApp->quit()).
|
||
//
|
||
// Установку выполняет НЕ это приложение, а свежераспакованная копия ARC.exe
|
||
// (в ней есть все Qt-DLL): она ждёт выхода текущего процесса, копирует файлы
|
||
// поверх install-папки (сохраняя database/), перезапускает установленный
|
||
// ARC.exe и самоудаляет временную папку.
|
||
class UpdateService final : public QObject {
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit UpdateService(QObject *parent = nullptr);
|
||
~UpdateService() override;
|
||
|
||
// Сравнение версий вида "MAJOR.MINOR.PATCH" покомпонентно как чисел.
|
||
// <0 если a<b, 0 если равны, >0 если a>b. Недостающие сегменты считаются 0,
|
||
// поэтому "1.0.9" < "1.0.64" (в отличие от строкового сравнения).
|
||
static int compareVersions(const QString &a, const QString &b);
|
||
|
||
public slots:
|
||
// Шаг 1. GET манифеста, сравнение с локальной версией из config.ini.
|
||
// Эмитит upToDate / updateAvailable / checkFailed.
|
||
void checkForUpdates();
|
||
|
||
// Шаг 2. Скачать zip → sha256 → распаковать → запустить апдейтер.
|
||
// Вызывается из UI после подтверждения пользователя (через invokeMethod).
|
||
// Эмитит downloadProgress по ходу, затем updateStaged либо stageFailed.
|
||
void downloadAndApply(const QString &zipUrl,
|
||
const QString &expectedSha256,
|
||
const QString &newVersion);
|
||
|
||
signals:
|
||
void upToDate(const QString ¤tVersion);
|
||
void updateAvailable(const QString &newVersion, const QString ¬es,
|
||
const QString &zipUrl, const QString &sha256);
|
||
void checkFailed(const QString &reason);
|
||
void downloadProgress(qint64 received, qint64 total);
|
||
void stageFailed(const QString &reason);
|
||
// Всё готово, апдейтер запущен. UI должен вызвать qApp->quit().
|
||
void updateStaged();
|
||
|
||
private:
|
||
QString m_manifestUrl;
|
||
QString m_currentVersion;
|
||
QNetworkAccessManager *m_manager;
|
||
|
||
bool downloadZip(const QString &zipUrl, const QString &destFile);
|
||
static bool verifySha256(const QString &file, const QString &expectedHex);
|
||
bool unpackZip(const QString &zipFile, const QString &destDir);
|
||
// Запускает <unpackedDir>/ARC.exe --apply-update с PID/путями. На не-Windows
|
||
// возвращает false (апдейтер только для Windows).
|
||
bool spawnUpdater(const QString &unpackedDir);
|
||
};
|