mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 19:26:39 +02:00
[Settings] 'Check for updates' button behavior changed (#4385)
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "http_client.h"
|
||||
#include "updating.h"
|
||||
#include "toast_notifications_helper.h"
|
||||
|
||||
#include <msi.h>
|
||||
#include <common/common.h>
|
||||
@@ -11,9 +13,6 @@
|
||||
#include <common/winstore.h>
|
||||
#include <common/notifications.h>
|
||||
|
||||
#include <winrt/Windows.Web.Http.h>
|
||||
#include <winrt/Windows.Web.Http.Headers.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.Management.Deployment.h>
|
||||
#include <winrt/Windows.Networking.Connectivity.h>
|
||||
|
||||
@@ -23,13 +22,10 @@ namespace
|
||||
{
|
||||
const wchar_t POWER_TOYS_UPGRADE_CODE[] = L"{42B84BF7-5FBF-473B-9C8B-049DC16F7708}";
|
||||
const wchar_t DONT_SHOW_AGAIN_RECORD_REGISTRY_PATH[] = L"delete_previous_powertoys_confirm";
|
||||
const wchar_t USER_AGENT[] = L"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
|
||||
const wchar_t LATEST_RELEASE_ENDPOINT[] = L"https://api.github.com/repos/microsoft/PowerToys/releases/latest";
|
||||
const wchar_t MSIX_PACKAGE_NAME[] = L"Microsoft.PowerToys";
|
||||
const wchar_t MSIX_PACKAGE_PUBLISHER[] = L"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
|
||||
|
||||
const wchar_t UPDATE_NOTIFY_TOAST_TAG[] = L"PTUpdateNotifyTag";
|
||||
const wchar_t UPDATE_READY_TOAST_TAG[] = L"PTUpdateReadyTag";
|
||||
const size_t MAX_DOWNLOAD_ATTEMPTS = 3;
|
||||
}
|
||||
|
||||
@@ -37,30 +33,10 @@ namespace localized_strings
|
||||
{
|
||||
const wchar_t OFFER_UNINSTALL_MSI[] = L"We've detected a previous installation of PowerToys. Would you like to remove it?";
|
||||
const wchar_t OFFER_UNINSTALL_MSI_TITLE[] = L"PowerToys: uninstall previous version?";
|
||||
const wchar_t UNINSTALLATION_SUCCESS[] = L"Previous version of PowerToys was uninstalled successfully.";
|
||||
const wchar_t UNINSTALLATION_UNKNOWN_ERROR[] = L"Error: please uninstall the previous version of PowerToys manually.";
|
||||
|
||||
const wchar_t GITHUB_NEW_VERSION_READY_TO_INSTALL[] = L"An update to PowerToys is ready to install.\n";
|
||||
const wchar_t GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR[] = L"Error: couldn't download PowerToys installer. Visit our GitHub page to update.\n";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_NOW[] = L"Update now";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART[] = L"At next launch";
|
||||
|
||||
const wchar_t GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT[] = L"An update to PowerToys is available. Visit our GitHub page to update.\n";
|
||||
const wchar_t GITHUB_NEW_VERSION_AGREE[] = L"Visit";
|
||||
const wchar_t GITHUB_NEW_VERSION_SNOOZE_TITLE[] = L"Click Snooze to be reminded in:";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D[] = L"1 day";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D[] = L"5 days";
|
||||
}
|
||||
|
||||
namespace updating
|
||||
{
|
||||
inline winrt::Windows::Web::Http::HttpClient create_http_client()
|
||||
{
|
||||
winrt::Windows::Web::Http::HttpClient client;
|
||||
auto headers = client.DefaultRequestHeaders();
|
||||
headers.UserAgent().TryParseAdd(USER_AGENT);
|
||||
return client;
|
||||
}
|
||||
|
||||
std::wstring get_msi_package_path()
|
||||
{
|
||||
std::wstring package_path;
|
||||
@@ -93,8 +69,8 @@ namespace updating
|
||||
|
||||
return package_path;
|
||||
}
|
||||
bool offer_msi_uninstallation()
|
||||
|
||||
bool offer_msi_uninstallation()
|
||||
{
|
||||
const auto selection = SHMessageBoxCheckW(nullptr, localized_strings::OFFER_UNINSTALL_MSI, localized_strings::OFFER_UNINSTALL_MSI_TITLE, MB_ICONQUESTION | MB_YESNO, IDNO, DONT_SHOW_AGAIN_RECORD_REGISTRY_PATH);
|
||||
return selection == IDYES;
|
||||
@@ -105,18 +81,18 @@ namespace updating
|
||||
const auto uninstall_result = MsiInstallProductW(package_path.c_str(), L"REMOVE=ALL");
|
||||
if (ERROR_SUCCESS == uninstall_result)
|
||||
{
|
||||
notifications::show_toast(localized_strings::UNINSTALLATION_SUCCESS);
|
||||
notifications::show_uninstallation_success();
|
||||
return true;
|
||||
}
|
||||
else if (auto system_message = get_last_error_message(uninstall_result); system_message.has_value())
|
||||
{
|
||||
try
|
||||
{
|
||||
notifications::show_toast(*system_message);
|
||||
::notifications::show_toast(*system_message);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
notifications::show_toast(localized_strings::UNINSTALLATION_UNKNOWN_ERROR);
|
||||
updating::notifications::show_uninstallation_error();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -126,10 +102,8 @@ namespace updating
|
||||
{
|
||||
try
|
||||
{
|
||||
auto client = create_http_client();
|
||||
auto response = co_await client.GetAsync(winrt::Windows::Foundation::Uri{ LATEST_RELEASE_ENDPOINT });
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
const auto body = co_await response.Content().ReadAsStringAsync();
|
||||
http::HttpClient client;
|
||||
const auto body = co_await client.request(winrt::Windows::Foundation::Uri{ LATEST_RELEASE_ENDPOINT });
|
||||
auto json_body = json::JsonValue::Parse(body).GetObjectW();
|
||||
auto new_version = json_body.GetNamedString(L"tag_name");
|
||||
winrt::Windows::Foundation::Uri release_page_uri{ json_body.GetNamedString(L"html_url") };
|
||||
@@ -213,16 +187,12 @@ namespace updating
|
||||
return { std::move(path_str) };
|
||||
}
|
||||
|
||||
std::future<void> try_download_file(const std::filesystem::path& destination, const winrt::Windows::Foundation::Uri& url)
|
||||
std::filesystem::path create_download_path()
|
||||
{
|
||||
namespace storage = winrt::Windows::Storage;
|
||||
|
||||
auto client = create_http_client();
|
||||
auto response = co_await client.GetAsync(url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
auto file_stream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(destination.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
co_await response.Content().WriteToStreamAsync(file_stream);
|
||||
file_stream.Close();
|
||||
auto installer_download_dst = get_pending_updates_path();
|
||||
std::error_code _;
|
||||
std::filesystem::create_directories(installer_download_dst, _);
|
||||
return installer_download_dst;
|
||||
}
|
||||
|
||||
std::future<void> try_autoupdate(const bool download_updates_automatically)
|
||||
@@ -232,24 +202,17 @@ namespace updating
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
using namespace localized_strings;
|
||||
auto current_version_to_next_version = VersionHelper{ VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION }.toWstring();
|
||||
current_version_to_next_version += L" -> ";
|
||||
current_version_to_next_version += new_version->version_string;
|
||||
|
||||
|
||||
if (download_updates_automatically && !could_be_costly_connection())
|
||||
{
|
||||
auto installer_download_dst = get_pending_updates_path();
|
||||
std::error_code _;
|
||||
std::filesystem::create_directories(installer_download_dst, _);
|
||||
installer_download_dst /= new_version->installer_filename;
|
||||
|
||||
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
|
||||
{
|
||||
co_await try_download_file(installer_download_dst, new_version->installer_download_url);
|
||||
http::HttpClient client;
|
||||
co_await client.download(new_version->installer_download_url, installer_download_dst);
|
||||
download_success = true;
|
||||
break;
|
||||
}
|
||||
@@ -260,32 +223,56 @@ namespace updating
|
||||
}
|
||||
if (!download_success)
|
||||
{
|
||||
notifications::toast_params toast_params{ UPDATE_NOTIFY_TOAST_TAG, false };
|
||||
std::wstring contents = GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR;
|
||||
contents += current_version_to_next_version;
|
||||
|
||||
notifications::show_toast_with_activations(std::move(contents), {}, { notifications::link_button{ GITHUB_NEW_VERSION_AGREE, new_version->release_page_uri.ToString().c_str() } }, std::move(toast_params));
|
||||
|
||||
updating::notifications::show_install_error(new_version.value());
|
||||
co_return;
|
||||
}
|
||||
|
||||
notifications::toast_params toast_params{ UPDATE_READY_TOAST_TAG, false };
|
||||
std::wstring new_version_ready{ GITHUB_NEW_VERSION_READY_TO_INSTALL };
|
||||
new_version_ready += current_version_to_next_version;
|
||||
|
||||
notifications::show_toast_with_activations(std::move(new_version_ready),
|
||||
{},
|
||||
{ notifications::link_button{ GITHUB_NEW_VERSION_UPDATE_NOW, L"powertoys://update_now/" + new_version->installer_filename },
|
||||
notifications::link_button{ GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART, L"powertoys://schedule_update/" + new_version->installer_filename },
|
||||
notifications::snooze_button{ GITHUB_NEW_VERSION_SNOOZE_TITLE, { { GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D, 24 * 60 }, { GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D, 120 * 60 } } } },
|
||||
std::move(toast_params));
|
||||
updating::notifications::show_version_ready(new_version.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
notifications::toast_params toast_params{ UPDATE_NOTIFY_TOAST_TAG, false };
|
||||
std::wstring contents = GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT;
|
||||
contents += current_version_to_next_version;
|
||||
notifications::show_toast_with_activations(std::move(contents), {}, { notifications::link_button{ GITHUB_NEW_VERSION_AGREE, new_version->release_page_uri.ToString().c_str() } }, std::move(toast_params));
|
||||
updating::notifications::show_visit_github(new_version.value());
|
||||
}
|
||||
}
|
||||
|
||||
std::future<void> check_new_version_available()
|
||||
{
|
||||
const auto new_version = co_await get_new_github_version_info_async();
|
||||
if (!new_version)
|
||||
{
|
||||
updating::notifications::show_unavailable();
|
||||
co_return;
|
||||
}
|
||||
|
||||
updating::notifications::show_available(new_version.value());
|
||||
}
|
||||
|
||||
std::future<std::wstring> download_update()
|
||||
{
|
||||
const auto new_version = co_await get_new_github_version_info_async();
|
||||
if (!new_version)
|
||||
{
|
||||
co_return L"";
|
||||
}
|
||||
|
||||
auto installer_download_dst = create_download_path() / new_version->installer_filename;
|
||||
updating::notifications::show_download_start(new_version.value());
|
||||
|
||||
try
|
||||
{
|
||||
auto progressUpdateHandle = [](float progress) {
|
||||
updating::notifications::update_download_progress(progress);
|
||||
};
|
||||
|
||||
http::HttpClient client;
|
||||
co_await client.download(new_version->installer_download_url, installer_download_dst, progressUpdateHandle);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
updating::notifications::show_install_error(new_version.value());
|
||||
co_return L"";
|
||||
}
|
||||
|
||||
co_return new_version->installer_filename;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user