2020-04-21 10:30:12 +03:00
|
|
|
#include "pch.h"
|
|
|
|
|
2020-10-22 19:02:59 +03:00
|
|
|
#include "Generated Files/resource.h"
|
|
|
|
|
2020-04-21 10:30:12 +03:00
|
|
|
#include "action_runner_utils.h"
|
|
|
|
#include "update_state.h"
|
|
|
|
#include "update_utils.h"
|
|
|
|
|
2020-11-20 11:34:34 +03:00
|
|
|
#include <common/updating/installer.h>
|
2020-04-21 10:30:12 +03:00
|
|
|
#include <common/updating/updating.h>
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/utils/resources.h>
|
|
|
|
#include <common/utils/timeutil.h>
|
2020-04-21 10:30:12 +03:00
|
|
|
#include <runner/general_settings.h>
|
|
|
|
|
2020-11-13 15:57:01 +03:00
|
|
|
auto Strings = create_notifications_strings();
|
2020-10-22 19:02:59 +03:00
|
|
|
|
2021-01-12 18:34:02 +03:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
constexpr int64_t UPDATE_CHECK_INTERVAL_MINUTES = 60 * 24;
|
|
|
|
constexpr int64_t UPDATE_CHECK_AFTER_FAILED_INTERVAL_MINUTES = 60 * 2;
|
|
|
|
}
|
|
|
|
|
2020-04-21 10:30:12 +03:00
|
|
|
bool start_msi_uninstallation_sequence()
|
|
|
|
{
|
|
|
|
const auto package_path = updating::get_msi_package_path();
|
|
|
|
|
|
|
|
if (package_path.empty())
|
|
|
|
{
|
|
|
|
// No MSI version detected
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-10-22 19:02:59 +03:00
|
|
|
if (!updating::offer_msi_uninstallation(Strings))
|
2020-04-21 10:30:12 +03:00
|
|
|
{
|
|
|
|
// User declined to uninstall or opted for "Don't show again"
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto sei = launch_action_runner(L"-uninstall_msi");
|
|
|
|
|
|
|
|
WaitForSingleObject(sei.hProcess, INFINITE);
|
|
|
|
DWORD exit_code = 0;
|
|
|
|
GetExitCodeProcess(sei.hProcess, &exit_code);
|
|
|
|
CloseHandle(sei.hProcess);
|
|
|
|
return exit_code == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void github_update_worker()
|
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
auto state = UpdateState::read();
|
|
|
|
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)
|
|
|
|
{
|
2021-01-12 18:34:02 +03:00
|
|
|
last_checked_minutes_ago = UPDATE_CHECK_INTERVAL_MINUTES;
|
2020-04-21 10:30:12 +03:00
|
|
|
}
|
2021-01-12 18:34:02 +03:00
|
|
|
sleep_minutes_till_next_update = max(0, UPDATE_CHECK_INTERVAL_MINUTES - last_checked_minutes_ago);
|
2020-04-21 10:30:12 +03:00
|
|
|
}
|
|
|
|
|
2021-01-12 18:34:02 +03:00
|
|
|
std::this_thread::sleep_for(std::chrono::minutes{ sleep_minutes_till_next_update });
|
2020-04-21 10:30:12 +03:00
|
|
|
const bool download_updates_automatically = get_general_settings().downloadUpdatesAutomatically;
|
2021-01-12 18:34:02 +03:00
|
|
|
bool update_check_ok = false;
|
2020-04-21 10:30:12 +03:00
|
|
|
try
|
|
|
|
{
|
2021-01-12 18:34:02 +03:00
|
|
|
update_check_ok = updating::try_autoupdate(download_updates_automatically, Strings).get();
|
2020-04-21 10:30:12 +03:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
// Couldn't autoupdate
|
2021-01-12 18:34:02 +03:00
|
|
|
update_check_ok = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (update_check_ok)
|
|
|
|
{
|
|
|
|
UpdateState::store([](UpdateState& state) {
|
|
|
|
state.github_update_last_checked_date.emplace(timeutil::now());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::this_thread::sleep_for(std::chrono::minutes{ UPDATE_CHECK_AFTER_FAILED_INTERVAL_MINUTES });
|
2020-04-21 10:30:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-12 18:34:02 +03:00
|
|
|
std::optional<updating::github_version_info> check_for_updates()
|
2020-06-23 15:53:02 +03:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2021-01-12 18:34:02 +03:00
|
|
|
auto version_check_result = updating::get_github_version_info_async(Strings).get();
|
|
|
|
if (!version_check_result)
|
2020-12-10 19:05:43 +03:00
|
|
|
{
|
2021-01-12 18:34:02 +03:00
|
|
|
updating::notifications::show_unavailable(Strings, std::move(version_check_result.error()));
|
2020-12-10 19:05:43 +03:00
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
2021-01-12 18:34:02 +03:00
|
|
|
if (std::holds_alternative<updating::version_up_to_date>(*version_check_result))
|
|
|
|
{
|
|
|
|
updating::notifications::show_unavailable(Strings, Strings.GITHUB_NEW_VERSION_UP_TO_DATE);
|
|
|
|
return std::move(*version_check_result);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto new_version = std::get<updating::new_version_download_info>(*version_check_result);
|
|
|
|
updating::notifications::show_available(new_version, Strings);
|
|
|
|
return std::move(new_version);
|
2020-06-23 15:53:02 +03:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
// Couldn't autoupdate
|
|
|
|
}
|
2020-12-10 19:05:43 +03:00
|
|
|
return std::nullopt;
|
2020-06-23 15:53:02 +03:00
|
|
|
}
|
|
|
|
|
2020-04-21 10:30:12 +03:00
|
|
|
bool launch_pending_update()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
auto update_state = UpdateState::read();
|
|
|
|
if (update_state.pending_update)
|
|
|
|
{
|
|
|
|
UpdateState::store([](UpdateState& state) {
|
|
|
|
state.pending_update = false;
|
2020-06-18 13:43:09 +03:00
|
|
|
state.pending_installer_filename = {};
|
2020-04-21 10:30:12 +03:00
|
|
|
});
|
2020-06-18 13:43:09 +03:00
|
|
|
std::wstring args{ UPDATE_NOW_LAUNCH_STAGE1_START_PT_CMDARG };
|
|
|
|
args += L' ';
|
|
|
|
args += update_state.pending_installer_filename;
|
|
|
|
|
|
|
|
launch_action_runner(args.c_str());
|
2020-04-21 10:30:12 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|