#pragma once #include #include 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 если a0 если 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 &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); // Запускает /ARC.exe --apply-update с PID/путями. На не-Windows // возвращает false (апдейтер только для Windows). bool spawnUpdater(const QString &unpackedDir); };