mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
runner: periodically check if there's a new version available on github and offer a visit
This commit is contained in:
committed by
Andrey Nekrasov
parent
c543b7585a
commit
0016836022
@@ -16,6 +16,11 @@
|
||||
#include <common/msi_to_msix_upgrade_lib/msi_to_msix_upgrade.h>
|
||||
#include <common/winstore.h>
|
||||
#include <common/notifications.h>
|
||||
#include <common/timeutil.h>
|
||||
|
||||
#include "update_state.h"
|
||||
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
#if _DEBUG && _WIN64
|
||||
#include "unhandled_exception_handler.h"
|
||||
@@ -26,6 +31,8 @@ extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
namespace localized_strings
|
||||
{
|
||||
const wchar_t MSI_VERSION_IS_ALREADY_RUNNING[] = L"An older version of PowerToys is already running.";
|
||||
const wchar_t GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT[] = L"An update to PowerToys is available. Visit our GitHub page to get ";
|
||||
const wchar_t GITHUB_NEW_VERSION_AGREE[] = L"Visit";
|
||||
}
|
||||
|
||||
namespace
|
||||
@@ -97,6 +104,46 @@ bool start_msi_uninstallation_sequence()
|
||||
return exit_code == 0;
|
||||
}
|
||||
|
||||
std::future<void> check_github_updates()
|
||||
{
|
||||
const auto new_version = co_await check_for_new_github_release_async();
|
||||
if (!new_version)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
using namespace localized_strings;
|
||||
|
||||
std::wstring contents = GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT;
|
||||
contents += new_version->version_string;
|
||||
contents += L'.';
|
||||
notifications::show_toast_with_activations(contents, {}, { notifications::link_button{ GITHUB_NEW_VERSION_AGREE, new_version->release_page_uri.ToString() } });
|
||||
}
|
||||
|
||||
void github_update_checking_worker()
|
||||
{
|
||||
const int64_t update_check_period_minutes = 60 * 24;
|
||||
|
||||
auto state = UpdateState::load();
|
||||
for (;;)
|
||||
{
|
||||
int64_t sleep_minutes_till_next_update = 0;
|
||||
if (state.github_update_last_checked_date.has_value())
|
||||
{
|
||||
int64_t last_checked_minutes_ago = timeutil::diff::in_minutes(timeutil::now(), *state.github_update_last_checked_date);
|
||||
if (last_checked_minutes_ago < 0)
|
||||
{
|
||||
last_checked_minutes_ago = update_check_period_minutes;
|
||||
}
|
||||
sleep_minutes_till_next_update = max(0, update_check_period_minutes - last_checked_minutes_ago);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::minutes(sleep_minutes_till_next_update));
|
||||
|
||||
check_github_updates().get();
|
||||
state.github_update_last_checked_date.emplace(timeutil::now());
|
||||
state.save();
|
||||
}
|
||||
}
|
||||
void alert_already_running()
|
||||
{
|
||||
MessageBoxW(nullptr,
|
||||
@@ -271,12 +318,17 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
try
|
||||
{
|
||||
|
||||
std::thread{ [] {
|
||||
github_update_checking_worker();
|
||||
} }.detach();
|
||||
|
||||
if (winstore::running_as_packaged())
|
||||
{
|
||||
std::thread{ [] {
|
||||
start_msi_uninstallation_sequence();
|
||||
} }.detach();
|
||||
}
|
||||
|
||||
// Singletons initialization order needs to be preserved, first events and
|
||||
// then modules to guarantee the reverse destruction order.
|
||||
SystemMenuHelperInstace();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<ImportGroup Label="Shared">
|
||||
<Import Project="..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
@@ -64,6 +64,7 @@
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\common\inc;..\common\Telemetry;..;..\modules;..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
@@ -88,6 +89,7 @@
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\common\inc;..\common\Telemetry;..;..\modules;..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
@@ -117,6 +119,7 @@
|
||||
<ClCompile Include="trace.cpp" />
|
||||
<ClCompile Include="tray_icon.cpp" />
|
||||
<ClCompile Include="unhandled_exception_handler.cpp" />
|
||||
<ClCompile Include="update_state.cpp" />
|
||||
<ClCompile Include="win_hook_event.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -124,6 +127,7 @@
|
||||
<ClInclude Include="general_settings.h" />
|
||||
<ClInclude Include="lowlevel_keyboard_event.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="update_state.h" />
|
||||
<ClInclude Include="powertoys_events.h" />
|
||||
<ClInclude Include="powertoy_module.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
<ClCompile Include="restart_elevated.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="update_state.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -79,6 +82,9 @@
|
||||
<ClInclude Include="restart_elevated.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="update_state.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Utils">
|
||||
|
||||
38
src/runner/update_state.cpp
Normal file
38
src/runner/update_state.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "pch.h"
|
||||
#include "update_state.h"
|
||||
|
||||
#include <common/json.h>
|
||||
#include <common/timeutil.h>
|
||||
#include <common/settings_helpers.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t PERSISTENT_STATE_FILENAME[] = L"\\update_state.json";
|
||||
}
|
||||
|
||||
UpdateState UpdateState::load()
|
||||
{
|
||||
const auto file_name = PTSettingsHelper::get_root_save_folder_location() + PERSISTENT_STATE_FILENAME;
|
||||
auto json = json::from_file(file_name);
|
||||
UpdateState state;
|
||||
|
||||
if (!json)
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
state.github_update_last_checked_date = timeutil::from_string(json->GetNamedString(L"github_update_last_checked_date", L"invalid").c_str());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void UpdateState::save()
|
||||
{
|
||||
json::JsonObject json;
|
||||
if (github_update_last_checked_date.has_value())
|
||||
{
|
||||
json.SetNamedValue(L"github_update_last_checked_date", json::value(timeutil::to_string(*github_update_last_checked_date)));
|
||||
}
|
||||
const auto file_name = PTSettingsHelper::get_root_save_folder_location() + PERSISTENT_STATE_FILENAME;
|
||||
json::to_file(file_name, json);
|
||||
}
|
||||
12
src/runner/update_state.h
Normal file
12
src/runner/update_state.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
#include <optional>
|
||||
|
||||
struct UpdateState
|
||||
{
|
||||
std::optional<std::time_t> github_update_last_checked_date;
|
||||
|
||||
static UpdateState load();
|
||||
void save();
|
||||
};
|
||||
Reference in New Issue
Block a user