mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
[Auto-update] Auto-update improvements (#11356)
* [Updating] Refactor autoupdate mechanism to use Settings window buttons * [Updating] Don't use underscores in update_state (#11029) * [Updating] Rename action_runner to be consisent with accepted format * [Updating] Make UpdateState values explicit * [Setup] Set default bootstrapper log severity to debug * [BugReport] Include all found bootstrapper logs * [Setup] Use capital letter for ActionRunner * [Updating] Simple UI to test UpdateState * [Action Runner] cleanup and coding style * [BugReportTool] fix coding convension * [Auto-update][PT Settings] Updated general page in the Settings (#11227) * [Auto-update][PT Settings] File watcher monitoring UpdateState.json (#11282) * Handle button clicks (#11288) * [Updating] Document ActionRunner cmd flags * [Auto-update][PT Settings] Updated UI (#11335) * [Updating] Do not reset update state when msi cancellation detected * [Updating] Directly launch update_now PT action instead of using custom URI scheme * Checking for updates UI (#11354) * [Updating] Fix cannotDownload state in action runner * [Updating] Reset update state to CannotDownload if action runner encountered an error * [Updating][PT Settings] downloading label, disable button in error state * Changed error message * [Updating rename CannotDownload to ErrorDownloading * [Updating] Add trace logging for Check for updates callback * [Updating][PT Settings] simplify downloading checks * [Updating][PT Settings] Updated text labels * [Updating][PT Settings] Retry to load settings if failed * [Updating][PT Settings] Text fix * [Updating][PT Settings] Installed version links removed * [Updating][PT Settings] Error text updated * [Updating][PT Settings] Show label after version checked * [Updating][PT Settings] Text foreground fix * [Updating][PT Settings] Clean up * [Updating] Do not reset releasePageUrl in case of error/cancellation * [Updating][PT Settings] fixed missing string * [Updating][PT Settings] checked for updates state fix Co-authored-by: yuyoyuppe <a.yuyoyuppe@gmail.com> Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com> Co-authored-by: Enrico Giordani <enrico.giordani@gmail.com>
This commit is contained in:
@@ -57,6 +57,5 @@ namespace notifications
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return timeutil::diff::in_days(timeutil::now(), last_disabled_time) < disable_interval_in_days;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ namespace updating
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
updating::notifications::show_uninstallation_error(strings);
|
||||
MessageBoxW(nullptr, strings.UNINSTALLATION_UNKNOWN_ERROR.c_str(), strings.NOTIFICATION_TITLE.c_str(), MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace updating
|
||||
namespace notifications
|
||||
{
|
||||
using namespace ::notifications;
|
||||
std::wstring current_version_to_next_version(const updating::new_version_download_info& info)
|
||||
std::wstring current_version_to_next_version(const new_version_download_info& info)
|
||||
{
|
||||
auto current_version_to_next_version = VersionHelper{ VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION }.toWstring();
|
||||
current_version_to_next_version += L" -> ";
|
||||
@@ -22,15 +22,7 @@ namespace updating
|
||||
return current_version_to_next_version;
|
||||
}
|
||||
|
||||
void show_unavailable(const notifications::strings& strings, std::wstring reason)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||
show_toast(std::move(reason), strings.TOAST_TITLE, std::move(toast_params));
|
||||
}
|
||||
|
||||
void show_available(const updating::new_version_download_info& info, const notifications::strings& strings)
|
||||
void show_new_version_available(const new_version_download_info& info, const strings& strings)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
@@ -40,106 +32,30 @@ namespace updating
|
||||
contents += current_version_to_next_version(info);
|
||||
|
||||
show_toast_with_activations(std::move(contents),
|
||||
strings.TOAST_TITLE,
|
||||
strings.NOTIFICATION_TITLE,
|
||||
{},
|
||||
{ link_button{ strings.GITHUB_NEW_VERSION_UPDATE_NOW,
|
||||
L"powertoys://download_and_install_update/" },
|
||||
L"powertoys://update_now/" },
|
||||
link_button{ strings.GITHUB_NEW_VERSION_MORE_INFO,
|
||||
info.release_page_uri.ToString().c_str() } },
|
||||
L"powertoys://open_settings/" } },
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
void show_download_start(const updating::new_version_download_info& info, const notifications::strings& strings)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
progress_bar_params progress_bar_params;
|
||||
std::wstring progress_title{ info.version.toWstring() };
|
||||
progress_title += L' ';
|
||||
progress_title += strings.DOWNLOAD_IN_PROGRESS;
|
||||
|
||||
progress_bar_params.progress_title = progress_title;
|
||||
progress_bar_params.progress = .0f;
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false, std::move(progress_bar_params) };
|
||||
show_toast_with_activations(strings.GITHUB_NEW_VERSION_DOWNLOAD_STARTED,
|
||||
strings.TOAST_TITLE,
|
||||
{},
|
||||
{},
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
void show_visit_github(const updating::new_version_download_info& info, const notifications::strings& strings)
|
||||
void show_open_settings_for_update(const strings& strings)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||
std::wstring contents = strings.GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT;
|
||||
contents += L'\n';
|
||||
contents += current_version_to_next_version(info);
|
||||
show_toast_with_activations(std::move(contents),
|
||||
strings.TOAST_TITLE,
|
||||
|
||||
std::vector<action_t> actions = {
|
||||
link_button{ strings.GITHUB_NEW_VERSION_MORE_INFO,
|
||||
L"powertoys://open_settings/" },
|
||||
};
|
||||
show_toast_with_activations(strings.GITHUB_NEW_VERSION_AVAILABLE,
|
||||
strings.NOTIFICATION_TITLE,
|
||||
{},
|
||||
{ link_button{ strings.GITHUB_NEW_VERSION_VISIT,
|
||||
info.release_page_uri.ToString().c_str() } },
|
||||
std::move(actions),
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
void show_install_error(const updating::new_version_download_info& info, const notifications::strings& strings)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||
std::wstring contents = strings.GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR;
|
||||
contents += L'\n';
|
||||
contents += current_version_to_next_version(info);
|
||||
show_toast_with_activations(std::move(contents),
|
||||
strings.TOAST_TITLE,
|
||||
{},
|
||||
{ link_button{ strings.GITHUB_NEW_VERSION_VISIT, info.release_page_uri.ToString().c_str() } },
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
void show_version_ready(const updating::new_version_download_info& info, const notifications::strings& strings)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||
std::wstring new_version_ready{ strings.GITHUB_NEW_VERSION_READY_TO_INSTALL };
|
||||
new_version_ready += L'\n';
|
||||
new_version_ready += current_version_to_next_version(info);
|
||||
|
||||
show_toast_with_activations(std::move(new_version_ready),
|
||||
strings.TOAST_TITLE,
|
||||
{},
|
||||
{ link_button{ strings.GITHUB_NEW_VERSION_UPDATE_NOW,
|
||||
L"powertoys://update_now/" + info.installer_filename },
|
||||
link_button{ strings.GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART,
|
||||
L"powertoys://schedule_update/" + info.installer_filename },
|
||||
snooze_button{
|
||||
strings.GITHUB_NEW_VERSION_SNOOZE_TITLE,
|
||||
{ { strings.GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D, 24 * 60 },
|
||||
{ strings.GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D, 120 * 60 } },
|
||||
strings.SNOOZE_BUTTON } },
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
void show_uninstallation_error(const notifications::strings& strings)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
show_toast(strings.UNINSTALLATION_UNKNOWN_ERROR, strings.TOAST_TITLE);
|
||||
}
|
||||
|
||||
void update_download_progress(const updating::new_version_download_info& info, float progress, const notifications::strings& strings)
|
||||
{
|
||||
progress_bar_params progress_bar_params;
|
||||
|
||||
std::wstring progress_title{ info.version.toWstring() };
|
||||
progress_title += L' ';
|
||||
progress_title += progress < 1 ? strings.DOWNLOAD_IN_PROGRESS : strings.DOWNLOAD_COMPLETE;
|
||||
progress_bar_params.progress_title = progress_title;
|
||||
progress_bar_params.progress = progress;
|
||||
update_toast_progress_bar(UPDATING_PROCESS_TOAST_TAG, progress_bar_params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,71 +10,31 @@ namespace updating
|
||||
{
|
||||
struct strings
|
||||
{
|
||||
std::wstring DOWNLOAD_COMPLETE;
|
||||
std::wstring DOWNLOAD_IN_PROGRESS;
|
||||
|
||||
std::wstring GITHUB_NEW_VERSION_ABORT;
|
||||
std::wstring GITHUB_NEW_VERSION_AVAILABLE;
|
||||
std::wstring GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT;
|
||||
std::wstring GITHUB_NEW_VERSION_CHECK_ERROR;
|
||||
std::wstring GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR;
|
||||
std::wstring GITHUB_NEW_VERSION_DOWNLOAD_STARTED;
|
||||
std::wstring GITHUB_NEW_VERSION_MORE_INFO;
|
||||
std::wstring GITHUB_NEW_VERSION_READY_TO_INSTALL;
|
||||
std::wstring GITHUB_NEW_VERSION_SNOOZE_TITLE;
|
||||
std::wstring GITHUB_NEW_VERSION_UP_TO_DATE;
|
||||
std::wstring GITHUB_NEW_VERSION_UPDATE_NOW;
|
||||
std::wstring GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART;
|
||||
std::wstring GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D;
|
||||
std::wstring GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D;
|
||||
std::wstring GITHUB_NEW_VERSION_USING_LOCAL_BUILD_ERROR;
|
||||
std::wstring GITHUB_NEW_VERSION_VISIT;
|
||||
|
||||
std::wstring OFFER_UNINSTALL_MSI;
|
||||
std::wstring OFFER_UNINSTALL_MSI_TITLE;
|
||||
|
||||
std::wstring SNOOZE_BUTTON;
|
||||
std::wstring TOAST_TITLE;
|
||||
std::wstring NOTIFICATION_TITLE;
|
||||
|
||||
std::wstring UNINSTALLATION_UNKNOWN_ERROR;
|
||||
};
|
||||
|
||||
void show_unavailable(const notifications::strings& strings, std::wstring reason);
|
||||
void show_available(const updating::new_version_download_info& info, const strings&);
|
||||
void show_download_start(const updating::new_version_download_info& info, const strings&);
|
||||
void show_visit_github(const updating::new_version_download_info& info, const strings&);
|
||||
void show_install_error(const updating::new_version_download_info& info, const strings&);
|
||||
void show_version_ready(const updating::new_version_download_info& info, const strings&);
|
||||
void show_uninstallation_error(const notifications::strings& strings);
|
||||
|
||||
void update_download_progress(const updating::new_version_download_info& info, float progress, const notifications::strings& strings);
|
||||
void show_new_version_available(const new_version_download_info& info, const strings& strings);
|
||||
void show_open_settings_for_update(const strings& strings);
|
||||
}
|
||||
}
|
||||
|
||||
#define create_notifications_strings() \
|
||||
::updating::notifications::strings \
|
||||
{ \
|
||||
.DOWNLOAD_COMPLETE = GET_RESOURCE_STRING(IDS_DOWNLOAD_COMPLETE), \
|
||||
.DOWNLOAD_IN_PROGRESS = GET_RESOURCE_STRING(IDS_DOWNLOAD_IN_PROGRESS), \
|
||||
.GITHUB_NEW_VERSION_ABORT = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_ABORT), \
|
||||
.GITHUB_NEW_VERSION_AVAILABLE = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_AVAILABLE), \
|
||||
.GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT), \
|
||||
.GITHUB_NEW_VERSION_CHECK_ERROR = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_CHECK_ERROR), \
|
||||
.GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR), \
|
||||
.GITHUB_NEW_VERSION_DOWNLOAD_STARTED = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_DOWNLOAD_STARTED), \
|
||||
.GITHUB_NEW_VERSION_MORE_INFO = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_MORE_INFO), \
|
||||
.GITHUB_NEW_VERSION_READY_TO_INSTALL = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_READY_TO_INSTALL), \
|
||||
.GITHUB_NEW_VERSION_SNOOZE_TITLE = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_SNOOZE_TITLE), \
|
||||
.GITHUB_NEW_VERSION_UP_TO_DATE = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UP_TO_DATE), \
|
||||
.GITHUB_NEW_VERSION_UPDATE_NOW = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_NOW), \
|
||||
.GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART), \
|
||||
.GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D), \
|
||||
.GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D), \
|
||||
.GITHUB_NEW_VERSION_USING_LOCAL_BUILD_ERROR = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_USING_LOCAL_BUILD_ERROR), \
|
||||
.GITHUB_NEW_VERSION_VISIT = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_VISIT), \
|
||||
.OFFER_UNINSTALL_MSI = GET_RESOURCE_STRING(IDS_OFFER_UNINSTALL_MSI), \
|
||||
.OFFER_UNINSTALL_MSI_TITLE = GET_RESOURCE_STRING(IDS_OFFER_UNINSTALL_MSI_TITLE), \
|
||||
.SNOOZE_BUTTON = GET_RESOURCE_STRING(IDS_SNOOZE_BUTTON), \
|
||||
.TOAST_TITLE = GET_RESOURCE_STRING(IDS_TOAST_TITLE), \
|
||||
.NOTIFICATION_TITLE = GET_RESOURCE_STRING(IDS_TOAST_TITLE), \
|
||||
.UNINSTALLATION_UNKNOWN_ERROR = GET_RESOURCE_STRING(IDS_UNINSTALLATION_UNKNOWN_ERROR) \
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Networking.Connectivity.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Management.Deployment.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
#include <wil/resource.h>
|
||||
|
||||
#endif //PCH_H
|
||||
|
||||
|
||||
70
src/common/updating/updateState.cpp
Normal file
70
src/common/updating/updateState.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "pch.h"
|
||||
#include "updateState.h"
|
||||
|
||||
#include <common/utils/json.h>
|
||||
#include <common/utils/timeutil.h>
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t PERSISTENT_STATE_FILENAME[] = L"\\UpdateState.json";
|
||||
const wchar_t UPDATE_STATE_MUTEX[] = L"Local\\PowerToysRunnerUpdateStateMutex";
|
||||
}
|
||||
|
||||
UpdateState deserialize(const json::JsonObject& json)
|
||||
{
|
||||
UpdateState result;
|
||||
|
||||
result.state = static_cast<UpdateState::State>(json.GetNamedNumber(L"state", UpdateState::upToDate));
|
||||
result.releasePageUrl = json.GetNamedString(L"releasePageUrl", L"");
|
||||
result.githubUpdateLastCheckedDate = timeutil::from_string(json.GetNamedString(L"githubUpdateLastCheckedDate", L"invalid").c_str());
|
||||
result.downloadedInstallerFilename = json.GetNamedString(L"downloadedInstallerFilename", L"");
|
||||
return result;
|
||||
}
|
||||
|
||||
json::JsonObject serialize(const UpdateState& state)
|
||||
{
|
||||
json::JsonObject json;
|
||||
|
||||
if (state.githubUpdateLastCheckedDate.has_value())
|
||||
{
|
||||
json.SetNamedValue(L"githubUpdateLastCheckedDate", json::value(timeutil::to_string(*state.githubUpdateLastCheckedDate)));
|
||||
}
|
||||
json.SetNamedValue(L"releasePageUrl", json::value(state.releasePageUrl));
|
||||
json.SetNamedValue(L"state", json::value(static_cast<double>(state.state)));
|
||||
json.SetNamedValue(L"downloadedInstallerFilename", json::value(state.downloadedInstallerFilename));
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
UpdateState UpdateState::read()
|
||||
{
|
||||
const auto filename = PTSettingsHelper::get_root_save_folder_location() + PERSISTENT_STATE_FILENAME;
|
||||
std::optional<json::JsonObject> json;
|
||||
{
|
||||
wil::unique_mutex_nothrow mutex{ CreateMutexW(nullptr, FALSE, UPDATE_STATE_MUTEX) };
|
||||
auto lock = mutex.acquire();
|
||||
json = json::from_file(filename);
|
||||
}
|
||||
return json ? deserialize(*json) : UpdateState{};
|
||||
}
|
||||
|
||||
void UpdateState::store(std::function<void(UpdateState&)> stateModifier)
|
||||
{
|
||||
const auto filename = PTSettingsHelper::get_root_save_folder_location() + PERSISTENT_STATE_FILENAME;
|
||||
|
||||
std::optional<json::JsonObject> json;
|
||||
{
|
||||
wil::unique_mutex_nothrow mutex{ CreateMutexW(nullptr, FALSE, UPDATE_STATE_MUTEX) };
|
||||
auto lock = mutex.acquire();
|
||||
json = json::from_file(filename);
|
||||
UpdateState state;
|
||||
if (json)
|
||||
{
|
||||
state = deserialize(*json);
|
||||
}
|
||||
stateModifier(state);
|
||||
json.emplace(serialize(state));
|
||||
json::to_file(filename, *json);
|
||||
}
|
||||
}
|
||||
25
src/common/updating/updateState.h
Normal file
25
src/common/updating/updateState.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
|
||||
// All fields must be default-initialized
|
||||
struct UpdateState
|
||||
{
|
||||
enum State
|
||||
{
|
||||
upToDate = 0,
|
||||
errorDownloading = 1,
|
||||
readyToDownload = 2,
|
||||
readyToInstall = 3
|
||||
} state = upToDate;
|
||||
std::wstring releasePageUrl;
|
||||
std::optional<std::time_t> githubUpdateLastCheckedDate;
|
||||
std::wstring downloadedInstallerFilename;
|
||||
|
||||
// To prevent concurrent modification of the file, we enforce this interface, which locks the file while
|
||||
// the state_modifier is active.
|
||||
static void store(std::function<void(UpdateState&)> stateModifier);
|
||||
static UpdateState read();
|
||||
};
|
||||
@@ -15,12 +15,27 @@ namespace // Strings in this namespace should not be localized
|
||||
{
|
||||
const wchar_t LATEST_RELEASE_ENDPOINT[] = L"https://api.github.com/repos/microsoft/PowerToys/releases/latest";
|
||||
const wchar_t ALL_RELEASES_ENDPOINT[] = L"https://api.github.com/repos/microsoft/PowerToys/releases";
|
||||
|
||||
const wchar_t LOCAL_BUILD_ERROR[] = L"Local build cannot be updated";
|
||||
const wchar_t NETWORK_ERROR[] = L"Network error";
|
||||
|
||||
const size_t MAX_DOWNLOAD_ATTEMPTS = 3;
|
||||
}
|
||||
|
||||
namespace updating
|
||||
{
|
||||
Uri extract_release_page_url(const json::JsonObject& release_object)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Uri{ release_object.GetNamedString(L"html_url") };
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<VersionHelper> extract_version_from_release_object(const json::JsonObject& release_object)
|
||||
{
|
||||
try
|
||||
@@ -66,7 +81,7 @@ namespace updating
|
||||
// If the current version starts with 0.0.*, it means we're on a local build from a farm and shouldn't check for updates.
|
||||
if (VERSION_MAJOR == 0 && VERSION_MINOR == 0)
|
||||
{
|
||||
co_return nonstd::make_unexpected(strings.GITHUB_NEW_VERSION_USING_LOCAL_BUILD_ERROR);
|
||||
co_return nonstd::make_unexpected(LOCAL_BUILD_ERROR);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -109,24 +124,16 @@ namespace updating
|
||||
co_return version_up_to_date{};
|
||||
}
|
||||
|
||||
Uri release_page_url{ release_object.GetNamedString(L"html_url") };
|
||||
auto installer_download_url = extract_installer_asset_download_info(release_object);
|
||||
co_return new_version_download_info{ std::move(release_page_url),
|
||||
auto [installer_download_url, installer_filename] = extract_installer_asset_download_info(release_object);
|
||||
co_return new_version_download_info{ extract_release_page_url(release_object),
|
||||
std::move(github_version),
|
||||
std::move(installer_download_url.first),
|
||||
std::move(installer_download_url.second) };
|
||||
std::move(installer_download_url),
|
||||
std::move(installer_filename) };
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
co_return nonstd::make_unexpected(strings.GITHUB_NEW_VERSION_CHECK_ERROR);
|
||||
}
|
||||
|
||||
bool could_be_costly_connection()
|
||||
{
|
||||
using namespace winrt::Windows::Networking::Connectivity;
|
||||
ConnectionProfile internetConnectionProfile = NetworkInformation::GetInternetConnectionProfile();
|
||||
return internetConnectionProfile.IsWwanConnectionProfile();
|
||||
co_return nonstd::make_unexpected(NETWORK_ERROR);
|
||||
}
|
||||
|
||||
std::filesystem::path get_pending_updates_path()
|
||||
@@ -136,86 +143,40 @@ namespace updating
|
||||
return { std::move(path_str) };
|
||||
}
|
||||
|
||||
std::filesystem::path create_download_path()
|
||||
std::optional<std::filesystem::path> create_download_path()
|
||||
{
|
||||
auto installer_download_dst = get_pending_updates_path();
|
||||
std::error_code _;
|
||||
std::filesystem::create_directories(installer_download_dst, _);
|
||||
return installer_download_dst;
|
||||
auto installer_download_path = get_pending_updates_path();
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(installer_download_path, ec);
|
||||
return !ec ? std::optional{ installer_download_path } : std::nullopt;
|
||||
}
|
||||
|
||||
std::future<bool> try_autoupdate(const bool download_updates_automatically, const notifications::strings& strings)
|
||||
std::future<std::optional<std::filesystem::path>> download_new_version(const new_version_download_info& new_version)
|
||||
{
|
||||
const auto version_check_result = co_await get_github_version_info_async(strings);
|
||||
if (!version_check_result)
|
||||
auto installer_download_path = create_download_path();
|
||||
if (!installer_download_path)
|
||||
{
|
||||
co_return false;
|
||||
co_return std::nullopt;
|
||||
}
|
||||
if (std::holds_alternative<version_up_to_date>(*version_check_result))
|
||||
{
|
||||
co_return true;
|
||||
}
|
||||
const auto new_version = std::get<new_version_download_info>(*version_check_result);
|
||||
|
||||
if (download_updates_automatically && !could_be_costly_connection())
|
||||
*installer_download_path /= new_version.installer_filename;
|
||||
|
||||
bool download_success = false;
|
||||
for (size_t i = 0; i < MAX_DOWNLOAD_ATTEMPTS; ++i)
|
||||
{
|
||||
auto installer_download_dst = create_download_path() / new_version.installer_filename;
|
||||
bool download_success = false;
|
||||
for (size_t i = 0; i < MAX_DOWNLOAD_ATTEMPTS; ++i)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
http::HttpClient client;
|
||||
co_await client.download(new_version.installer_download_url, installer_download_dst);
|
||||
download_success = true;
|
||||
break;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// reattempt to download or do nothing
|
||||
}
|
||||
http::HttpClient client;
|
||||
co_await client.download(new_version.installer_download_url, *installer_download_path);
|
||||
download_success = true;
|
||||
break;
|
||||
}
|
||||
if (!download_success)
|
||||
catch (...)
|
||||
{
|
||||
updating::notifications::show_install_error(new_version, strings);
|
||||
co_return false;
|
||||
// reattempt to download or do nothing
|
||||
}
|
||||
|
||||
updating::notifications::show_version_ready(new_version, strings);
|
||||
}
|
||||
else
|
||||
{
|
||||
updating::notifications::show_visit_github(new_version, strings);
|
||||
}
|
||||
co_return true;
|
||||
co_return download_success ? installer_download_path : std::nullopt;
|
||||
}
|
||||
|
||||
std::future<std::wstring> download_update(const notifications::strings& strings)
|
||||
{
|
||||
const auto version_check_result = co_await get_github_version_info_async(strings);
|
||||
if (!version_check_result || std::holds_alternative<version_up_to_date>(*version_check_result))
|
||||
{
|
||||
co_return L"";
|
||||
}
|
||||
const auto new_version = std::get<new_version_download_info>(*version_check_result);
|
||||
auto installer_download_dst = create_download_path() / new_version.installer_filename;
|
||||
updating::notifications::show_download_start(new_version, strings);
|
||||
|
||||
try
|
||||
{
|
||||
auto progressUpdateHandle = [&](float progress) {
|
||||
updating::notifications::update_download_progress(new_version, progress, strings);
|
||||
};
|
||||
|
||||
http::HttpClient client;
|
||||
co_await client.download(new_version.installer_download_url, installer_download_dst, progressUpdateHandle);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
updating::notifications::show_install_error(new_version, strings);
|
||||
co_return L"";
|
||||
}
|
||||
|
||||
co_return new_version.installer_filename;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
namespace updating
|
||||
{
|
||||
using winrt::Windows::Foundation::Uri;
|
||||
struct version_up_to_date {};
|
||||
using github_version_info = std::variant<new_version_download_info, version_up_to_date>;
|
||||
|
||||
struct version_up_to_date
|
||||
{
|
||||
};
|
||||
struct new_version_download_info
|
||||
{
|
||||
Uri release_page_uri = nullptr;
|
||||
@@ -24,11 +24,10 @@ namespace updating
|
||||
Uri installer_download_url = nullptr;
|
||||
std::wstring installer_filename;
|
||||
};
|
||||
using github_version_info = std::variant<new_version_download_info, version_up_to_date>;
|
||||
|
||||
// Returns whether the update check has succeeded
|
||||
std::future<bool> try_autoupdate(const bool download_updates_automatically, const notifications::strings&);
|
||||
std::future<std::optional<std::filesystem::path>> download_new_version(const new_version_download_info& new_version);
|
||||
std::filesystem::path get_pending_updates_path();
|
||||
std::future<std::wstring> download_update(const notifications::strings&);
|
||||
std::future<nonstd::expected<github_version_info, std::wstring>> get_github_version_info_async(const notifications::strings& strings, const bool prerelease = false);
|
||||
|
||||
// non-localized
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<ClInclude Include="installer.h" />
|
||||
<ClInclude Include="notifications.h" />
|
||||
<ClInclude Include="updating.h" />
|
||||
<ClInclude Include="updateState.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="winstore.h" />
|
||||
</ItemGroup>
|
||||
@@ -49,6 +50,7 @@
|
||||
<ClCompile Include="installer.cpp" />
|
||||
<ClCompile Include="notifications.cpp" />
|
||||
<ClCompile Include="updating.cpp" />
|
||||
<ClCompile Include="updateState.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
||||
Reference in New Issue
Block a user