Dev/yuyoyuppe/autoupdate polishing (#11693)
* [Updating] Create a dedicated executable project for updating procedures * [Updating] Use PowerToys.Update for update procedures (#11495) * [Updating] Use PowerToys.Update for update procedures * [Setup] Remove toast notifications and other dependencies from bootstrapper * [Installer] Remove Winstore, redundant strings * [Settings] Remove deprecated 'packaged' setting
This commit is contained in:
parent
5b804a1ff6
commit
cdd06d7e98
|
@ -65,6 +65,7 @@ build:
|
|||
to: 'Build_Output'
|
||||
include:
|
||||
- 'PowerToys.ActionRunner.exe'
|
||||
- 'PowerToys.Update.exe'
|
||||
- 'BackgroundActivatorDLL.dll'
|
||||
- 'Notifications.dll'
|
||||
- 'os-detection.dll'
|
||||
|
|
|
@ -272,8 +272,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interop", "interop", "{5A78
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "log", "log", "{E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinStore", "src\common\WinStore\Winstore.vcxproj", "{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "COMUtils", "src\common\COMUtils\COMUtils.vcxproj", "{7319089E-46D6-4400-BC65-E39BDF1416EE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Display", "src\common\Display\Display.vcxproj", "{CABA8DFB-823B-4BF2-93AC-3F31984150D9}"
|
||||
|
@ -288,8 +286,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{B39DC643
|
|||
src\common\utils\EventLocker.h = src\common\utils\EventLocker.h
|
||||
src\common\utils\EventWaiter.h = src\common\utils\EventWaiter.h
|
||||
src\common\utils\exec.h = src\common\utils\exec.h
|
||||
src\common\utils\HttpClient.h = src\common\utils\HttpClient.h
|
||||
src\common\utils\json.h = src\common\utils\json.h
|
||||
src\common\utils\logger_helper.h = src\common\utils\logger_helper.h
|
||||
src\common\utils\MsiUtils.h = src\common\utils\MsiUtils.h
|
||||
src\common\utils\os-detect.h = src\common\utils\os-detect.h
|
||||
src\common\utils\process_path.h = src\common\utils\process_path.h
|
||||
src\common\utils\ProcessWaiter.h = src\common\utils\ProcessWaiter.h
|
||||
|
@ -345,6 +345,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuideModuleInterfac
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuide", "src\modules\ShortcutGuide\ShortcutGuide\ShortcutGuide.vcxproj", "{2EDB3EB4-FA92-4BFF-B2D8-566584837231}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.Update", "src\Update\PowerToys.Update.vcxproj", "{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.WindowsSettings", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj", "{5043CECE-E6A7-4867-9CBE-02D27D83747A}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -623,10 +625,6 @@ Global
|
|||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.Build.0 = Debug|x64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.ActiveCfg = Release|x64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.Build.0 = Release|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Debug|x64.Build.0 = Debug|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Release|x64.ActiveCfg = Release|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Release|x64.Build.0 = Release|x64
|
||||
{7319089E-46D6-4400-BC65-E39BDF1416EE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7319089E-46D6-4400-BC65-E39BDF1416EE}.Debug|x64.Build.0 = Debug|x64
|
||||
{7319089E-46D6-4400-BC65-E39BDF1416EE}.Release|x64.ActiveCfg = Release|x64
|
||||
|
@ -679,22 +677,22 @@ Global
|
|||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.Build.0 = Debug|x64
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.ActiveCfg = Release|x64
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.Build.0 = Release|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Debug|x64.Build.0 = Debug|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Release|x64.ActiveCfg = Release|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Release|x64.Build.0 = Release|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Debug|x64.Build.0 = Debug|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Release|x64.ActiveCfg = Release|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Release|x64.Build.0 = Release|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Debug|x64.Build.0 = Debug|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Release|x64.ActiveCfg = Release|x64
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Release|x64.Build.0 = Release|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Debug|x64.Build.0 = Debug|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Release|x64.ActiveCfg = Release|x64
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A}.Release|x64.Build.0 = Release|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Release|x64.Build.0 = Release|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Debug|x64.Build.0 = Debug|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Release|x64.ActiveCfg = Release|x64
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A}.Release|x64.Build.0 = Release|x64
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Debug|x64.Build.0 = Debug|x64
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Release|x64.ActiveCfg = Release|x64
|
||||
|
@ -703,6 +701,10 @@ Global
|
|||
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Debug|x64.Build.0 = Debug|x64
|
||||
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.ActiveCfg = Release|x64
|
||||
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.Build.0 = Release|x64
|
||||
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Debug|x64.Build.0 = Debug|x64
|
||||
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Release|x64.ActiveCfg = Release|x64
|
||||
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Release|x64.Build.0 = Release|x64
|
||||
{5043CECE-E6A7-4867-9CBE-02D27D83747A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5043CECE-E6A7-4867-9CBE-02D27D83747A}.Debug|x64.Build.0 = Debug|x64
|
||||
{5043CECE-E6A7-4867-9CBE-02D27D83747A}.Release|x64.ActiveCfg = Release|x64
|
||||
|
@ -789,7 +791,6 @@ Global
|
|||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{5A7818A8-109C-4E1C-850D-1A654E234B0E} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{E4E03FE0-94FD-47C7-88C5-F17D0AA549D3} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{7319089E-46D6-4400-BC65-E39BDF1416EE} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{CABA8DFB-823B-4BF2-93AC-3F31984150D9} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{98537082-0FDB-40DE-ABD8-0DC5A4269BAB} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
|
@ -806,8 +807,8 @@ Global
|
|||
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{127F38E0-40AA-4594-B955-5616BF206882} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{106CBECA-0701-4FC3-838C-9DF816A19AE2} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
|
|
|
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30320.27
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Updating", "..\..\src\common\updating\updating.vcxproj", "{17DA04DF-E393-4397-9CF0-84DABE11032E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bootstrapper", "bootstrapper\bootstrapper.vcxproj", "{D194E3AA-F824-4CA9-9A58-034DD6B7D022}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "..\..\src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
|
||||
|
@ -13,20 +11,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Version", "..\..\src\common
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetttingsAPI", "..\..\src\common\SettingsAPI\SetttingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Notifications", "..\..\src\common\notifications\notifications.vcxproj", "{1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinStore", "..\..\src\common\WinStore\Winstore.vcxproj", "{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.Build.0 = Debug|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.ActiveCfg = Release|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.Build.0 = Release|x64
|
||||
{D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.Build.0 = Debug|x64
|
||||
{D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Release|x64.ActiveCfg = Release|x64
|
||||
|
@ -43,14 +33,6 @@ Global
|
|||
{6955446D-23F7-4023-9BB3-8657F904AF99}.Debug|x64.Build.0 = Debug|x64
|
||||
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.ActiveCfg = Release|x64
|
||||
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.Build.0 = Release|x64
|
||||
{1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525}.Debug|x64.Build.0 = Debug|x64
|
||||
{1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525}.Release|x64.ActiveCfg = Release|x64
|
||||
{1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525}.Release|x64.Build.0 = Release|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Debug|x64.Build.0 = Debug|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Release|x64.ActiveCfg = Release|x64
|
||||
{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include "dotnet_installation.h"
|
||||
#include "http_client.h"
|
||||
|
||||
#include "utils/exec.h"
|
||||
#include "utils/winapi_error.h"
|
||||
#include "DotnetInstallation.h"
|
||||
|
||||
#include <common/utils/exec.h>
|
||||
#include <common/utils/HttpClient.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace updating
|
|
@ -67,30 +67,9 @@
|
|||
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
||||
<value>PowerToys installation error</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE" xml:space="preserve">
|
||||
<value>An update to PowerToys is available.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_UPDATE_NOW" xml:space="preserve">
|
||||
<value>Update now</value>
|
||||
</data>
|
||||
<data name="UNINSTALLATION_UNKNOWN_ERROR" xml:space="preserve">
|
||||
<value>Error: please uninstall the previous version of PowerToys manually.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT" xml:space="preserve">
|
||||
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_MORE_INFO" xml:space="preserve">
|
||||
<value>More info...</value>
|
||||
</data>
|
||||
<data name="TOAST_TITLE" xml:space="preserve">
|
||||
<value>PowerToys Update</value>
|
||||
</data>
|
||||
<data name="OFFER_UNINSTALL_MSI" xml:space="preserve">
|
||||
<value>We've detected a previous installation of PowerToys. Would you like to remove it?</value>
|
||||
</data>
|
||||
<data name="OFFER_UNINSTALL_MSI_TITLE" xml:space="preserve">
|
||||
<value>PowerToys: uninstall previous version?</value>
|
||||
</data>
|
||||
<data name="INSTALLER_EXTRACT_ERROR" xml:space="preserve">
|
||||
<value>Couldn't extract MSI installer.</value>
|
||||
</data>
|
||||
|
|
|
@ -2,23 +2,21 @@
|
|||
#include "Generated Files/resource.h"
|
||||
|
||||
#include "RcResource.h"
|
||||
#include <common/updating/dotnet_installation.h>
|
||||
#include <common/updating/installer.h>
|
||||
#include <common/updating/notifications.h>
|
||||
#include <common/version/helper.h>
|
||||
#include <common/version/version.h>
|
||||
#include <common/utils/appMutex.h>
|
||||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/MsiUtils.h>
|
||||
#include <common/utils/os-detect.h>
|
||||
#include <common/utils/processApi.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/window.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
|
||||
#include <runner/action_runner_utils.h>
|
||||
|
||||
#include "DotnetInstallation.h"
|
||||
#include "progressbar_window.h"
|
||||
|
||||
auto Strings = create_notifications_strings();
|
||||
static bool g_Silent = false;
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
|
@ -95,7 +93,7 @@ void CleanupSettingsFromOlderVersions()
|
|||
spdlog::info("Old log settings file wasn't found");
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
catch (...)
|
||||
{
|
||||
spdlog::error("Failed to cleanup old log settings");
|
||||
}
|
||||
|
@ -106,9 +104,9 @@ void ShowMessageBoxError(const wchar_t* message)
|
|||
if (!g_Silent)
|
||||
{
|
||||
MessageBoxW(nullptr,
|
||||
message,
|
||||
GET_RESOURCE_STRING(IDS_BOOTSTRAPPER_PROGRESS_TITLE).c_str(),
|
||||
MB_OK | MB_ICONERROR);
|
||||
message,
|
||||
GET_RESOURCE_STRING(IDS_BOOTSTRAPPER_PROGRESS_TITLE).c_str(),
|
||||
MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +115,46 @@ void ShowMessageBoxError(const UINT messageId)
|
|||
ShowMessageBoxError(GET_RESOURCE_STRING(messageId).c_str());
|
||||
}
|
||||
|
||||
bool uninstall_msi_version(const std::wstring& package_path)
|
||||
{
|
||||
const auto uninstall_result = MsiInstallProductW(package_path.c_str(), L"REMOVE=ALL");
|
||||
return ERROR_SUCCESS == uninstall_result;
|
||||
}
|
||||
|
||||
std::optional<VersionHelper> get_installed_powertoys_version()
|
||||
{
|
||||
auto installed_path = GetMsiPackageInstalledPath();
|
||||
if (!installed_path)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
*installed_path += L"\\PowerToys.exe";
|
||||
|
||||
// Get the version information for the file requested
|
||||
const DWORD fvSize = GetFileVersionInfoSizeW(installed_path->c_str(), nullptr);
|
||||
if (!fvSize)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto pbVersionInfo = std::make_unique<BYTE[]>(fvSize);
|
||||
|
||||
if (!GetFileVersionInfoW(installed_path->c_str(), 0, fvSize, pbVersionInfo.get()))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
VS_FIXEDFILEINFO* fileInfo = nullptr;
|
||||
UINT fileInfoLen = 0;
|
||||
if (!VerQueryValueW(pbVersionInfo.get(), L"\\", reinterpret_cast<LPVOID*>(&fileInfo), &fileInfoLen))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return VersionHelper{ (fileInfo->dwFileVersionMS >> 16) & 0xffff,
|
||||
(fileInfo->dwFileVersionMS >> 0) & 0xffff,
|
||||
(fileInfo->dwFileVersionLS >> 16) & 0xffff };
|
||||
}
|
||||
|
||||
int Bootstrapper(HINSTANCE hInstance)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
|
@ -133,17 +171,17 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||
cxxopts::Options options{ "PowerToysBootstrapper" };
|
||||
|
||||
// clang-format off
|
||||
options.add_options()
|
||||
("h,help", "Show help")
|
||||
("no_full_ui", "Use reduced UI for MSI")
|
||||
("s,silent", "Suppress all UI, notifications and does not start PowerToys")
|
||||
("no_start_pt", "Do not launch PowerToys after the installation is complete")
|
||||
("start_pt", "Always launch PowerToys after the installation is complete")
|
||||
("skip_dotnet_install", "Skip dotnet 3.X installation even if it's not detected")
|
||||
("log_level", "Log level. Possible values: off|debug|error", cxxopts::value<std::string>()->default_value("off"))
|
||||
("log_dir", "Log directory", cxxopts::value<std::string>()->default_value("."))
|
||||
("install_dir", "Installation directory", cxxopts::value<std::string>()->default_value(defaultInstallDir))
|
||||
("extract_msi", "Extract MSI to the working directory and exit. Use only if you must access MSI directly.");
|
||||
options.add_options()
|
||||
("h,help", "Show help")
|
||||
("no_full_ui", "Use reduced UI for MSI")
|
||||
("s,silent", "Suppress all UI, notifications and does not start PowerToys")
|
||||
("no_start_pt", "Do not launch PowerToys after the installation is complete")
|
||||
("start_pt", "Always launch PowerToys after the installation is complete")
|
||||
("skip_dotnet_install", "Skip dotnet 3.X installation even if it's not detected")
|
||||
("log_level", "Log level. Possible values: off|debug|error", cxxopts::value<std::string>()->default_value("off"))
|
||||
("log_dir", "Log directory", cxxopts::value<std::string>()->default_value("."))
|
||||
("install_dir", "Installation directory", cxxopts::value<std::string>()->default_value(defaultInstallDir))
|
||||
("extract_msi", "Extract MSI to the working directory and exit. Use only if you must access MSI directly.");
|
||||
// clang-format on
|
||||
|
||||
cxxopts::ParseResult cmdArgs;
|
||||
|
@ -234,15 +272,15 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||
const VersionHelper myVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
|
||||
|
||||
// Do not support installing on Windows < 1903
|
||||
if (updating::is_1809_or_older())
|
||||
if (!Is19H1OrHigher())
|
||||
{
|
||||
ShowMessageBoxError(IDS_OLD_WINDOWS_ERROR);
|
||||
spdlog::error("PowerToys {} requires at least Windows 1903 to run.", myVersion.toString());
|
||||
return 1;
|
||||
ShowMessageBoxError(IDS_OLD_WINDOWS_ERROR);
|
||||
spdlog::error("PowerToys {} requires at least Windows 1903 to run.", myVersion.toString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if there's a newer version installed
|
||||
const auto installedVersion = updating::get_installed_powertoys_version();
|
||||
const auto installedVersion = get_installed_powertoys_version();
|
||||
if (installedVersion && *installedVersion >= myVersion)
|
||||
{
|
||||
spdlog::error(L"Detected a newer version {} vs {}", (*installedVersion).toWstring(), myVersion.toWstring());
|
||||
|
@ -341,7 +379,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||
});
|
||||
|
||||
spdlog::debug("Acquiring existing MSI package path if exists");
|
||||
const auto package_path = updating::get_msi_package_path();
|
||||
const auto package_path = GetMsiPackagePath();
|
||||
if (!package_path.empty())
|
||||
{
|
||||
spdlog::debug(L"Existing MSI package path found: {}", package_path);
|
||||
|
@ -351,7 +389,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||
spdlog::debug("Existing MSI package path not found");
|
||||
}
|
||||
|
||||
if (!package_path.empty() && !updating::uninstall_msi_version(package_path, Strings))
|
||||
if (!package_path.empty() && !uninstall_msi_version(package_path))
|
||||
{
|
||||
spdlog::error("Couldn't install the existing MSI package ({})", GetLastError());
|
||||
ShowMessageBoxError(IDS_UNINSTALL_PREVIOUS_VERSION_ERROR);
|
||||
|
@ -401,7 +439,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||
spdlog::error("Unknown exception during dotnet installation");
|
||||
ShowMessageBoxError(IDS_DOTNET_INSTALL_ERROR);
|
||||
}
|
||||
|
||||
|
||||
// At this point, there's no reason to show progress bar window, since MSI installers have their own
|
||||
CloseProgressBarDialog();
|
||||
|
||||
|
@ -419,7 +457,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||
if ((!noStartPT && !g_Silent) || startPT)
|
||||
{
|
||||
spdlog::debug("Starting the newly installed PowerToys.exe");
|
||||
auto newPTPath = updating::get_msi_package_installed_path();
|
||||
auto newPTPath = GetMsiPackageInstalledPath();
|
||||
if (!newPTPath)
|
||||
{
|
||||
spdlog::error("Couldn't determine new MSI package install location ({})", GetLastError());
|
||||
|
@ -448,7 +486,7 @@ int WINAPI WinMain(HINSTANCE hi, HINSTANCE, LPSTR, int)
|
|||
std::string messageA{ "Unhandled std exception encountered\n" };
|
||||
messageA.append(ex.what());
|
||||
|
||||
spdlog::error(messageA.c_str());
|
||||
spdlog::error(messageA.c_str());
|
||||
|
||||
std::wstring messageW{};
|
||||
std::copy(messageA.begin(), messageA.end(), messageW.begin());
|
||||
|
|
|
@ -24,7 +24,9 @@
|
|||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{D194E3AA-F824-4CA9-9A58-034DD6B7D022}</ProjectGuid>
|
||||
<RootNamespace>bootstrapper</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<OverrideWindowsTargetPlatformVersion>true</OverrideWindowsTargetPlatformVersion>
|
||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>bootstrapper</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
|
@ -71,7 +73,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
|
@ -88,12 +90,12 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>WindowsApp.lib;Msi.lib;Shlwapi.lib;Comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>WindowsApp.lib;Msi.lib;Shlwapi.lib;Comctl32.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
|
@ -106,11 +108,12 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>WindowsApp.lib;Msi.lib;Shlwapi.lib;Comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>WindowsApp.lib;Msi.lib;Shlwapi.lib;Comctl32.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="bootstrapper.cpp" />
|
||||
<ClCompile Include="DotnetInstallation.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
|
@ -119,6 +122,7 @@
|
|||
<ClCompile Include="RcResource.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DotnetInstallation.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="progressbar_window.h" />
|
||||
</ItemGroup>
|
||||
|
@ -133,8 +137,11 @@
|
|||
<Image Include="..\runner\svgs\icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\common\updating\updating.vcxproj">
|
||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
||||
<ProjectReference Include="..\..\..\src\common\SettingsAPI\SetttingsAPI.vcxproj">
|
||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\src\common\version\version.vcxproj">
|
||||
<Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\src\logging\logging.vcxproj">
|
||||
<Project>{7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f}</Project>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <shellapi.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <charconv>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
#include <fstream>
|
||||
|
@ -22,8 +23,10 @@
|
|||
#include <spdlog/sinks/null_sink.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <cxxopts.hpp>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include <common/updating/notifications.h>
|
||||
#include <common/utils/window.h>
|
||||
|
||||
#include "progressbar_window.h"
|
||||
|
|
|
@ -359,6 +359,9 @@
|
|||
<Component Id="PowerToys_ActionRunner_exe" Guid="626ABB17-16F0-4007-9A58-6998724A5E14" Win64="yes">
|
||||
<File Id="PowerToys.ActionRunner.exe" KeyPath="yes" Checksum="yes" />
|
||||
</Component>
|
||||
<Component Id="PowerToys_Update_exe" Guid="446D0AD4-AA8F-45BA-BDAC-6C620DF77AFF" Win64="yes">
|
||||
<File Id="PowerToys.Update.exe" KeyPath="yes" Checksum="yes" />
|
||||
</Component>
|
||||
<Component Id="License_rtf" Guid="3E5AE43B-CFB4-449B-A346-94CAAFF3312E" Win64="yes">
|
||||
<File Source="$(var.RepoDir)\installer\License.rtf" Id="License.rtf" KeyPath="yes" />
|
||||
</Component>
|
||||
|
@ -869,6 +872,7 @@
|
|||
<ComponentRef Id="PowerToysStartMenuShortcut"/>
|
||||
<ComponentRef Id="BackgroundActivator_dll" />
|
||||
<ComponentRef Id="PowerToys_ActionRunner_exe" />
|
||||
<ComponentRef Id="PowerToys_Update_exe" />
|
||||
<ComponentRef Id="powertoys_toast_clsid" />
|
||||
<ComponentRef Id="License_rtf" />
|
||||
<ComponentRef Id="Notice_md" />
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <ProjectTelemetry.h>
|
||||
|
||||
#include "../../src/common/utils/MsiUtils.h"
|
||||
#include "../../src/common/updating/installer.h"
|
||||
#include "../../src/common/version/version.h"
|
||||
|
||||
|
@ -582,7 +583,7 @@ UINT __stdcall DetectPrevInstallPathCA(MSIHANDLE hInstall)
|
|||
|
||||
try
|
||||
{
|
||||
if (auto install_path = updating::get_msi_package_installed_path())
|
||||
if (auto install_path = GetMsiPackageInstalledPath())
|
||||
{
|
||||
MsiSetPropertyW(hInstall, L"INSTALLFOLDER", install_path->data());
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(WIX)sdk\$(WixPlatformToolset)\lib\x64;$(SolutionDir)\packages\WiX.3.11.2\tools\sdk\vs2017\lib\x64;..\..\$(PlatformShortName)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;ApplicationUpdate.lib;Notifications.lib;winstore.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;ApplicationUpdate.lib;Notifications.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
|
|
@ -64,28 +64,7 @@
|
|||
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
||||
<value>PowerToys installation error</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE" xml:space="preserve">
|
||||
<value>An update to PowerToys is available.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_UPDATE_NOW" xml:space="preserve">
|
||||
<value>Update now</value>
|
||||
</data>
|
||||
<data name="UNINSTALLATION_UNKNOWN_ERROR" xml:space="preserve">
|
||||
<value>Error: please uninstall the previous version of PowerToys manually.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT" xml:space="preserve">
|
||||
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_MORE_INFO" xml:space="preserve">
|
||||
<value>More info...</value>
|
||||
</data>
|
||||
<data name="TOAST_TITLE" xml:space="preserve">
|
||||
<value>PowerToys Update</value>
|
||||
</data>
|
||||
<data name="OFFER_UNINSTALL_MSI" xml:space="preserve">
|
||||
<value>We've detected a previous installation of PowerToys. Would you like to remove it?</value>
|
||||
</data>
|
||||
<data name="OFFER_UNINSTALL_MSI_TITLE" xml:space="preserve">
|
||||
<value>PowerToys: uninstall previous version?</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -11,12 +11,6 @@
|
|||
#include <filesystem>
|
||||
#include <string_view>
|
||||
|
||||
#include <common/updating/updating.h>
|
||||
#include <common/updating/updateState.h>
|
||||
#include <common/updating/installer.h>
|
||||
#include <common/updating/http_client.h>
|
||||
#include <common/updating/dotnet_installation.h>
|
||||
|
||||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/resources.h>
|
||||
|
@ -28,214 +22,14 @@
|
|||
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <Msi.h>
|
||||
|
||||
#include "../runner/tray_icon.h"
|
||||
#include "../runner/action_runner_utils.h"
|
||||
|
||||
auto Strings = create_notifications_strings();
|
||||
#include "../runner/ActionRunnerUtils.h"
|
||||
|
||||
using namespace cmdArg;
|
||||
|
||||
int UninstallMsiAction()
|
||||
{
|
||||
const auto package_path = updating::get_msi_package_path();
|
||||
if (package_path.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!updating::uninstall_msi_version(package_path, Strings))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Launch PowerToys again, since it's been terminated by the MSI uninstaller
|
||||
std::wstring runner_path{ winrt::Windows::ApplicationModel::Package::Current().InstalledLocation().Path() };
|
||||
runner_path += L"\\PowerToys.exe";
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC };
|
||||
sei.lpFile = runner_path.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
ShellExecuteExW(&sei);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::optional<fs::path> CopySelfToTempDir()
|
||||
{
|
||||
std::error_code error;
|
||||
auto dst_path = fs::temp_directory_path() / "PowerToys.ActionRunner.exe";
|
||||
fs::copy_file(get_module_filename(), dst_path, fs::copy_options::overwrite_existing, error);
|
||||
if (error)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::move(dst_path);
|
||||
}
|
||||
|
||||
std::optional<fs::path> ObtainInstallerPath()
|
||||
{
|
||||
using namespace updating;
|
||||
|
||||
auto state = UpdateState::read();
|
||||
if (state.state == UpdateState::readyToDownload || state.state == UpdateState::errorDownloading)
|
||||
{
|
||||
const auto new_version_info = get_github_version_info_async(Strings).get();
|
||||
if (!new_version_info)
|
||||
{
|
||||
Logger::error(L"Couldn't obtain github version info: {}", new_version_info.error());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (!std::holds_alternative<new_version_download_info>(*new_version_info))
|
||||
{
|
||||
Logger::error("Invoked with -update_now argument, but no update was available");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto downloaded_installer = download_new_version(std::get<new_version_download_info>(*new_version_info)).get();
|
||||
if (!downloaded_installer)
|
||||
{
|
||||
Logger::error("Couldn't download new installer");
|
||||
}
|
||||
|
||||
return downloaded_installer;
|
||||
}
|
||||
else if (state.state == UpdateState::readyToInstall)
|
||||
{
|
||||
fs::path installer{ get_pending_updates_path() / state.downloadedInstallerFilename };
|
||||
if (fs::is_regular_file(installer))
|
||||
{
|
||||
return std::move(installer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error(L"Couldn't find a downloaded installer {}", installer.native());
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error("Invoked with -update_now argument, but update state was invalid");
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool InstallNewVersionStage1()
|
||||
{
|
||||
const auto installer = ObtainInstallerPath();
|
||||
if (!installer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto copy_in_temp = CopySelfToTempDir())
|
||||
{
|
||||
// Detect if PT was running
|
||||
const auto pt_main_window = FindWindowW(pt_tray_icon_window_class, nullptr);
|
||||
const bool launch_powertoys = pt_main_window != nullptr;
|
||||
if (pt_main_window != nullptr)
|
||||
{
|
||||
SendMessageW(pt_main_window, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
std::wstring arguments{ UPDATE_NOW_LAUNCH_STAGE2 };
|
||||
arguments += L" \"";
|
||||
arguments += installer->c_str();
|
||||
arguments += L"\" \"";
|
||||
arguments += get_module_folderpath();
|
||||
arguments += L"\" ";
|
||||
arguments += launch_powertoys ? UPDATE_STAGE2_RESTART_PT : UPDATE_STAGE2_DONT_START_PT;
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC };
|
||||
sei.lpFile = copy_in_temp->c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
|
||||
sei.lpParameters = arguments.c_str();
|
||||
return ShellExecuteExW(&sei) == TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool InstallNewVersionStage2(std::wstring installer_path, std::wstring_view install_path, bool launch_powertoys)
|
||||
{
|
||||
std::transform(begin(installer_path), end(installer_path), begin(installer_path), ::towlower);
|
||||
|
||||
bool success = true;
|
||||
|
||||
if (installer_path.ends_with(L".msi"))
|
||||
{
|
||||
success = MsiInstallProductW(installer_path.data(), nullptr) == ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's not .msi, then it's our .exe installer
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE };
|
||||
sei.lpFile = installer_path.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
std::wstring parameters = L"--no_full_ui";
|
||||
if (launch_powertoys)
|
||||
{
|
||||
// .exe installer launches the main app by default
|
||||
launch_powertoys = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters += L"--no_start_pt";
|
||||
}
|
||||
|
||||
sei.lpParameters = parameters.c_str();
|
||||
|
||||
success = ShellExecuteExW(&sei) == TRUE;
|
||||
|
||||
// Wait for the install completion
|
||||
if (success)
|
||||
{
|
||||
WaitForSingleObject(sei.hProcess, INFINITE);
|
||||
DWORD exitCode = 0;
|
||||
GetExitCodeProcess(sei.hProcess, &exitCode);
|
||||
success = exitCode == 0;
|
||||
CloseHandle(sei.hProcess);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code _;
|
||||
fs::remove(installer_path, _);
|
||||
|
||||
UpdateState::store([&](UpdateState& state) {
|
||||
state = {};
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
state.state = UpdateState::upToDate;
|
||||
});
|
||||
|
||||
if (launch_powertoys)
|
||||
{
|
||||
std::wstring new_pt_path{ install_path };
|
||||
new_pt_path += L"\\PowerToys.exe";
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC };
|
||||
sei.lpFile = new_pt_path.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpParameters = UPDATE_REPORT_SUCCESS;
|
||||
return ShellExecuteExW(&sei) == TRUE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||
{
|
||||
int nArgs = 0;
|
||||
|
@ -312,37 +106,6 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (action == UNINSTALL_MSI)
|
||||
{
|
||||
return UninstallMsiAction();
|
||||
}
|
||||
else if (action == UPDATE_NOW_LAUNCH_STAGE1)
|
||||
{
|
||||
const bool failed = !InstallNewVersionStage1();
|
||||
if (failed)
|
||||
{
|
||||
UpdateState::store([&](UpdateState& state) {
|
||||
state.downloadedInstallerFilename = {};
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
state.state = UpdateState::errorDownloading;
|
||||
});
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
else if (action == UPDATE_NOW_LAUNCH_STAGE2)
|
||||
{
|
||||
using namespace std::string_view_literals;
|
||||
const bool failed = !InstallNewVersionStage2(args[2], args[3], args[4] == std::wstring_view{ UPDATE_STAGE2_RESTART_PT });
|
||||
if (failed)
|
||||
{
|
||||
UpdateState::store([&](UpdateState& state) {
|
||||
state.downloadedInstallerFilename = {};
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
state.state = UpdateState::errorDownloading;
|
||||
});
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,15 +41,9 @@
|
|||
<ProjectReference Include="..\common\logger\logger.vcxproj">
|
||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\notifications\notifications.vcxproj">
|
||||
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\SettingsAPI\SetttingsAPI.vcxproj">
|
||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\updating\updating.vcxproj">
|
||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
|
|
14
src/Update/LocProject.json
Normal file
14
src/Update/LocProject.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"Projects": [
|
||||
{
|
||||
"LanguageSet": "Azure_Languages",
|
||||
"LocItems": [
|
||||
{
|
||||
"SourceFile": "src\\Update\\Resources.resx",
|
||||
"CopyOption": "LangIDOnName",
|
||||
"OutputPath": "src\\Update"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
36
src/Update/PowerToys.Update.base.rc
Normal file
36
src/Update/PowerToys.Update.base.rc
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../common/version/version.h"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION FILE_VERSION
|
||||
PRODUCTVERSION PRODUCT_VERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||
BEGIN
|
||||
VALUE "CompanyName", COMPANY_NAME
|
||||
VALUE "FileDescription", FILE_DESCRIPTION
|
||||
VALUE "FileVersion", FILE_VERSION_STRING
|
||||
VALUE "InternalName", INTERNAL_NAME
|
||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||
VALUE "ProductName", PRODUCT_NAME
|
||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||
END
|
||||
END
|
255
src/Update/PowerToys.Update.cpp
Normal file
255
src/Update/PowerToys.Update.cpp
Normal file
|
@ -0,0 +1,255 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include "Generated Files/resource.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
|
||||
#include <common/updating/updating.h>
|
||||
#include <common/updating/updateState.h>
|
||||
#include <common/updating/installer.h>
|
||||
|
||||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/HttpClient.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/timeutil.h>
|
||||
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <Msi.h>
|
||||
|
||||
#include "../runner/tray_icon.h"
|
||||
#include "../runner/UpdateUtils.h"
|
||||
|
||||
using namespace cmdArg;
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::optional<fs::path> CopySelfToTempDir()
|
||||
{
|
||||
std::error_code error;
|
||||
auto dst_path = fs::temp_directory_path() / "PowerToys.Update.exe";
|
||||
fs::copy_file(get_module_filename(), dst_path, fs::copy_options::overwrite_existing, error);
|
||||
if (error)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::move(dst_path);
|
||||
}
|
||||
|
||||
std::optional<fs::path> ObtainInstallerPath()
|
||||
{
|
||||
using namespace updating;
|
||||
|
||||
auto state = UpdateState::read();
|
||||
if (state.state == UpdateState::readyToDownload || state.state == UpdateState::errorDownloading)
|
||||
{
|
||||
const auto new_version_info = get_github_version_info_async().get();
|
||||
if (!new_version_info)
|
||||
{
|
||||
Logger::error(L"Couldn't obtain github version info: {}", new_version_info.error());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (!std::holds_alternative<new_version_download_info>(*new_version_info))
|
||||
{
|
||||
Logger::error("Invoked with -update_now argument, but no update was available");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto downloaded_installer = download_new_version(std::get<new_version_download_info>(*new_version_info)).get();
|
||||
if (!downloaded_installer)
|
||||
{
|
||||
Logger::error("Couldn't download new installer");
|
||||
}
|
||||
|
||||
return downloaded_installer;
|
||||
}
|
||||
else if (state.state == UpdateState::readyToInstall)
|
||||
{
|
||||
fs::path installer{ get_pending_updates_path() / state.downloadedInstallerFilename };
|
||||
if (fs::is_regular_file(installer))
|
||||
{
|
||||
return std::move(installer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error(L"Couldn't find a downloaded installer {}", installer.native());
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error("Invoked with -update_now argument, but update state was invalid");
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool InstallNewVersionStage1()
|
||||
{
|
||||
const auto installer = ObtainInstallerPath();
|
||||
if (!installer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto copy_in_temp = CopySelfToTempDir())
|
||||
{
|
||||
// Detect if PT was running
|
||||
const auto pt_main_window = FindWindowW(pt_tray_icon_window_class, nullptr);
|
||||
const bool launch_powertoys = pt_main_window != nullptr;
|
||||
if (pt_main_window != nullptr)
|
||||
{
|
||||
SendMessageW(pt_main_window, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
std::wstring arguments{ UPDATE_NOW_LAUNCH_STAGE2 };
|
||||
arguments += L" \"";
|
||||
arguments += installer->c_str();
|
||||
arguments += L"\" \"";
|
||||
arguments += get_module_folderpath();
|
||||
arguments += L"\" ";
|
||||
arguments += launch_powertoys ? UPDATE_STAGE2_RESTART_PT : UPDATE_STAGE2_DONT_START_PT;
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC };
|
||||
sei.lpFile = copy_in_temp->c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
|
||||
sei.lpParameters = arguments.c_str();
|
||||
return ShellExecuteExW(&sei) == TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool InstallNewVersionStage2(std::wstring installer_path, std::wstring_view install_path, bool launch_powertoys)
|
||||
{
|
||||
std::transform(begin(installer_path), end(installer_path), begin(installer_path), ::towlower);
|
||||
|
||||
bool success = true;
|
||||
|
||||
if (installer_path.ends_with(L".msi"))
|
||||
{
|
||||
success = MsiInstallProductW(installer_path.data(), nullptr) == ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's not .msi, then it's our .exe installer
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE };
|
||||
sei.lpFile = installer_path.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
std::wstring parameters = L"--no_full_ui";
|
||||
if (launch_powertoys)
|
||||
{
|
||||
// .exe installer launches the main app by default
|
||||
launch_powertoys = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters += L"--no_start_pt";
|
||||
}
|
||||
|
||||
sei.lpParameters = parameters.c_str();
|
||||
|
||||
success = ShellExecuteExW(&sei) == TRUE;
|
||||
|
||||
// Wait for the install completion
|
||||
if (success)
|
||||
{
|
||||
WaitForSingleObject(sei.hProcess, INFINITE);
|
||||
DWORD exitCode = 0;
|
||||
GetExitCodeProcess(sei.hProcess, &exitCode);
|
||||
success = exitCode == 0;
|
||||
CloseHandle(sei.hProcess);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code _;
|
||||
fs::remove(installer_path, _);
|
||||
|
||||
UpdateState::store([&](UpdateState& state) {
|
||||
state = {};
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
state.state = UpdateState::upToDate;
|
||||
});
|
||||
|
||||
if (launch_powertoys)
|
||||
{
|
||||
std::wstring new_pt_path{ install_path };
|
||||
new_pt_path += L"\\PowerToys.exe";
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC };
|
||||
sei.lpFile = new_pt_path.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpParameters = UPDATE_REPORT_SUCCESS;
|
||||
return ShellExecuteExW(&sei) == TRUE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||
{
|
||||
int nArgs = 0;
|
||||
LPWSTR* args = CommandLineToArgvW(GetCommandLineW(), &nArgs);
|
||||
if (!args || nArgs < 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::wstring_view action{ args[1] };
|
||||
|
||||
std::filesystem::path logFilePath(PTSettingsHelper::get_root_save_folder_location());
|
||||
logFilePath.append(LogSettings::updateLogPath);
|
||||
Logger::init(LogSettings::updateLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
if (action == UPDATE_NOW_LAUNCH_STAGE1)
|
||||
{
|
||||
const bool failed = !InstallNewVersionStage1();
|
||||
if (failed)
|
||||
{
|
||||
UpdateState::store([&](UpdateState& state) {
|
||||
state.downloadedInstallerFilename = {};
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
state.state = UpdateState::errorDownloading;
|
||||
});
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
else if (action == UPDATE_NOW_LAUNCH_STAGE2)
|
||||
{
|
||||
using namespace std::string_view_literals;
|
||||
const bool failed = !InstallNewVersionStage2(args[2], args[3], args[4] == std::wstring_view{ UPDATE_STAGE2_RESTART_PT });
|
||||
if (failed)
|
||||
{
|
||||
UpdateState::store([&](UpdateState& state) {
|
||||
state.downloadedInstallerFilename = {};
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
state.state = UpdateState::errorDownloading;
|
||||
});
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
76
src/Update/PowerToys.Update.vcxproj
Normal file
76
src/Update/PowerToys.Update.vcxproj
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h PowerToys.Update.base.rc PowerToys.Update.rc" />
|
||||
</Target>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}</ProjectGuid>
|
||||
<RootNamespace>Update</RootNamespace>
|
||||
<ProjectName>PowerToys.Update</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\..\deps\expected.props" />
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup>
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>WindowsApp.lib;Msi.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="PowerToys.Update.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\common\logger\logger.vcxproj">
|
||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\notifications\notifications.vcxproj">
|
||||
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\SettingsAPI\SetttingsAPI.vcxproj">
|
||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\updating\updating.vcxproj">
|
||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PowerToys.Update.base.rc" />
|
||||
<ResourceCompile Include="Generated Files\PowerToys.Update.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
82
src/Update/Resources.resx
Normal file
82
src/Update/Resources.resx
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="DOTNET_CORE_DOWNLOAD_FAILURE" xml:space="preserve">
|
||||
<value>Couldn't download .NET Core Desktop Runtime 3.1, please install it manually.</value>
|
||||
</data>
|
||||
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
||||
<value>PowerToys installation error</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE" xml:space="preserve">
|
||||
<value>An update to PowerToys is available.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_UPDATE_NOW" xml:space="preserve">
|
||||
<value>Update now</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT" xml:space="preserve">
|
||||
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_MORE_INFO" xml:space="preserve">
|
||||
<value>More info...</value>
|
||||
</data>
|
||||
<data name="TOAST_TITLE" xml:space="preserve">
|
||||
<value>PowerToys Update</value>
|
||||
</data>
|
||||
</root>
|
11
src/Update/resource.base.h
Normal file
11
src/Update/resource.base.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by PowerToys.Update.rc
|
||||
|
||||
//////////////////////////////
|
||||
// Non-localizable
|
||||
|
||||
#define FILE_DESCRIPTION "PowerToys Update"
|
||||
#define INTERNAL_NAME "PowerToys.Update"
|
||||
#define ORIGINAL_FILENAME "PowerToys.Update.exe"
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{C502A854-53AC-4EBB-8DC0-E4AF2191E4F6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>WinStore</RootNamespace>
|
||||
<ProjectName>WinStore</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="winstore.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="winstore.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,70 +0,0 @@
|
|||
#include "winstore.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <appmodel.h>
|
||||
|
||||
using winrt::Windows::ApplicationModel::StartupTask;
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t* STARTUP_TASKID = L"PowerToysStartupTaskID";
|
||||
}
|
||||
|
||||
namespace winstore
|
||||
{
|
||||
bool running_as_packaged()
|
||||
{
|
||||
UINT32 length = 0;
|
||||
const auto rc = GetPackageFamilyName(GetCurrentProcess(), &length, nullptr);
|
||||
return rc != APPMODEL_ERROR_NO_PACKAGE;
|
||||
}
|
||||
|
||||
std::future<StartupTaskState> get_startup_task_status_async()
|
||||
{
|
||||
const auto startupTask = co_await StartupTask::GetAsync(STARTUP_TASKID);
|
||||
co_return startupTask.State();
|
||||
}
|
||||
|
||||
std::future<void> switch_startup_task_state_async(const bool enabled)
|
||||
{
|
||||
const auto startupTask = co_await StartupTask::GetAsync(STARTUP_TASKID);
|
||||
enum class action
|
||||
{
|
||||
none,
|
||||
enable,
|
||||
disable,
|
||||
} action_to_try = action::none;
|
||||
switch (startupTask.State())
|
||||
{
|
||||
case StartupTaskState::Disabled:
|
||||
if (enabled)
|
||||
{
|
||||
action_to_try = action::enable;
|
||||
}
|
||||
break;
|
||||
case StartupTaskState::Enabled:
|
||||
if (!enabled)
|
||||
{
|
||||
action_to_try = action::disable;
|
||||
}
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
switch (action_to_try)
|
||||
{
|
||||
case action::enable:
|
||||
co_await startupTask.RequestEnableAsync();
|
||||
break;
|
||||
case action::disable:
|
||||
startupTask.Disable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// We can't handle the error, in case we don't have a permission to change startup task state
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <future>
|
||||
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
|
||||
namespace winstore
|
||||
{
|
||||
using winrt::Windows::ApplicationModel::StartupTaskState;
|
||||
|
||||
bool running_as_packaged();
|
||||
std::future<void> switch_startup_task_state_async(const bool enabled);
|
||||
std::future<StartupTaskState> get_startup_task_status_async();
|
||||
}
|
|
@ -11,6 +11,8 @@ struct LogSettings
|
|||
inline const static std::wstring runnerLogPath = L"RunnerLogs\\runner-log.txt";
|
||||
inline const static std::string actionRunnerLoggerName = "action-runner";
|
||||
inline const static std::wstring actionRunnerLogPath = L"RunnerLogs\\action-runner-log.txt";
|
||||
inline const static std::string updateLoggerName = "update";
|
||||
inline const static std::wstring updateLogPath = L"UpdateLogs\\update-log.txt";
|
||||
inline const static std::string launcherLoggerName = "launcher";
|
||||
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
|
||||
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.txt";
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "notifications.h"
|
||||
#include "utils/com_object_factory.h"
|
||||
#include "utils/window.h"
|
||||
#include "winstore/winstore.h"
|
||||
|
||||
#include <unknwn.h>
|
||||
#include <winrt/base.h>
|
||||
|
@ -201,41 +200,6 @@ void notifications::override_application_id(const std::wstring_view appID)
|
|||
SetCurrentProcessExplicitAppUserModelID(APPLICATION_ID.c_str());
|
||||
}
|
||||
|
||||
void notifications::register_background_toast_handler()
|
||||
{
|
||||
if (!winstore::running_as_packaged())
|
||||
{
|
||||
// The WIX installer will have us registered via the registry
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
// Re-request access to clean up from previous PowerToys installations
|
||||
BackgroundExecutionManager::RemoveAccess();
|
||||
BackgroundExecutionManager::RequestAccessAsync().get();
|
||||
|
||||
BackgroundTaskBuilder builder;
|
||||
ToastNotificationActionTrigger trigger{ PACKAGED_APPLICATION_ID };
|
||||
builder.SetTrigger(trigger);
|
||||
builder.TaskEntryPoint(TASK_ENTRYPOINT);
|
||||
builder.Name(TASK_NAME);
|
||||
|
||||
const auto tasks = BackgroundTaskRegistration::AllTasks();
|
||||
const bool already_registered = std::any_of(begin(tasks), end(tasks), [=](const auto& task) {
|
||||
return task.Value().Name() == TASK_NAME;
|
||||
});
|
||||
if (already_registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
(void)builder.Register();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Couldn't register the background task, nothing we can do
|
||||
}
|
||||
}
|
||||
|
||||
void notifications::show_toast(std::wstring message, std::wstring title, toast_params params)
|
||||
{
|
||||
// The toast won't be actually activated in the background, since it doesn't have any buttons
|
||||
|
@ -402,8 +366,8 @@ void notifications::show_toast_with_activations(std::wstring message,
|
|||
NotificationData data{ map };
|
||||
notification.Data(std::move(data));
|
||||
|
||||
const auto notifier = winstore::running_as_packaged() ? ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
const auto notifier =
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
|
||||
// Set a tag-related params if it has a valid length
|
||||
if (params.tag.has_value() && params.tag->length() < 64)
|
||||
|
@ -431,9 +395,8 @@ void notifications::show_toast_with_activations(std::wstring message,
|
|||
|
||||
void notifications::update_toast_progress_bar(std::wstring_view tag, progress_bar_params params)
|
||||
{
|
||||
const auto notifier = winstore::running_as_packaged() ?
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
const auto notifier =
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
|
||||
float progress = std::clamp(params.progress, 0.0f, 1.0f);
|
||||
winrt::Windows::Foundation::Collections::StringMap map;
|
||||
|
@ -468,8 +431,7 @@ void notifications::remove_toasts_by_tag(std::wstring_view tag)
|
|||
|
||||
void notifications::remove_all_scheduled_toasts()
|
||||
{
|
||||
const auto notifier = winstore::running_as_packaged() ? ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
const auto notifier = ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace notifications
|
|||
constexpr inline const wchar_t UPDATING_PROCESS_TOAST_TAG[] = L"PTUpdateNotifyTag";
|
||||
|
||||
void override_application_id(const std::wstring_view appID);
|
||||
void register_background_toast_handler();
|
||||
void run_desktop_app_activator_loop();
|
||||
|
||||
bool register_application_id(const std::wstring_view appName, const std::wstring_view iconPath);
|
||||
|
|
|
@ -39,11 +39,6 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WinStore\Winstore.vcxproj">
|
||||
<Project>{c502a854-53ac-4ebb-8dc0-e4af2191e4f6}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "http_client.h"
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Web.Http.Headers.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
|
||||
namespace http
|
||||
{
|
||||
using namespace winrt::Windows::Web::Http;
|
||||
namespace storage = winrt::Windows::Storage;
|
||||
|
||||
const wchar_t USER_AGENT[] = L"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
|
||||
|
||||
HttpClient::HttpClient()
|
||||
{
|
||||
auto headers = m_client.DefaultRequestHeaders();
|
||||
headers.UserAgent().TryParseAdd(USER_AGENT);
|
||||
}
|
||||
|
||||
std::future<std::wstring> HttpClient::request(const winrt::Windows::Foundation::Uri& url)
|
||||
{
|
||||
auto response = co_await m_client.GetAsync(url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
auto body = co_await response.Content().ReadAsStringAsync();
|
||||
co_return std::wstring(body);
|
||||
}
|
||||
|
||||
std::future<void> HttpClient::download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFilePath)
|
||||
{
|
||||
auto response = co_await m_client.GetAsync(url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
auto file_stream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(dstFilePath.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
co_await response.Content().WriteToStreamAsync(file_stream);
|
||||
file_stream.Close();
|
||||
}
|
||||
|
||||
std::future<void> HttpClient::download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFilePath, const std::function<void(float)>& progressUpdateCallback)
|
||||
{
|
||||
auto response = co_await m_client.GetAsync(url, HttpCompletionOption::ResponseHeadersRead);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
uint64_t totalBytes = response.Content().Headers().ContentLength().GetUInt64();
|
||||
auto contentStream = co_await response.Content().ReadAsInputStreamAsync();
|
||||
|
||||
uint64_t totalBytesRead = 0;
|
||||
storage::Streams::Buffer buffer(8192);
|
||||
auto fileStream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(dstFilePath.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
|
||||
co_await contentStream.ReadAsync(buffer, buffer.Capacity(), storage::Streams::InputStreamOptions::None);
|
||||
while (buffer.Length() > 0)
|
||||
{
|
||||
co_await fileStream.WriteAsync(buffer);
|
||||
totalBytesRead += buffer.Length();
|
||||
if (progressUpdateCallback)
|
||||
{
|
||||
float percentage = (float)totalBytesRead / totalBytes;
|
||||
progressUpdateCallback(percentage);
|
||||
}
|
||||
|
||||
co_await contentStream.ReadAsync(buffer, buffer.Capacity(), storage::Streams::InputStreamOptions::None);
|
||||
}
|
||||
|
||||
if (progressUpdateCallback)
|
||||
{
|
||||
progressUpdateCallback(1);
|
||||
}
|
||||
|
||||
fileStream.Close();
|
||||
contentStream.Close();
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <winrt/Windows.Web.Http.h>
|
||||
|
||||
namespace http
|
||||
{
|
||||
class HttpClient
|
||||
{
|
||||
public:
|
||||
HttpClient();
|
||||
std::future<std::wstring> request(const winrt::Windows::Foundation::Uri& url);
|
||||
std::future<void> download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFle);
|
||||
std::future<void> download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFle, const std::function<void(float)>& progressUpdateCallback);
|
||||
|
||||
private:
|
||||
winrt::Windows::Web::Http::HttpClient m_client;
|
||||
};
|
||||
}
|
|
@ -2,171 +2,22 @@
|
|||
|
||||
#include "installer.h"
|
||||
#include <common/version/version.h>
|
||||
#include <common/notifications/notifications.h>
|
||||
#include <common/utils/MsiUtils.h>
|
||||
#include <common/utils/os-detect.h>
|
||||
#include "utils/winapi_error.h"
|
||||
|
||||
namespace // Strings in this namespace should not be localized
|
||||
{
|
||||
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 TOAST_TITLE[] = L"PowerToys";
|
||||
|
||||
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 POWERTOYS_EXE_COMPONENT[] = L"{A2C66D91-3485-4D00-B04D-91844E6B345B}";
|
||||
}
|
||||
|
||||
namespace updating
|
||||
{
|
||||
std::wstring get_msi_package_path()
|
||||
{
|
||||
std::wstring package_path;
|
||||
wchar_t GUID_product_string[39];
|
||||
if (const bool found = ERROR_SUCCESS == MsiEnumRelatedProductsW(POWER_TOYS_UPGRADE_CODE, 0, 0, GUID_product_string); !found)
|
||||
{
|
||||
return package_path;
|
||||
}
|
||||
|
||||
if (const bool installed = INSTALLSTATE_DEFAULT == MsiQueryProductStateW(GUID_product_string); !installed)
|
||||
{
|
||||
return package_path;
|
||||
}
|
||||
|
||||
DWORD package_path_size = 0;
|
||||
|
||||
if (const bool has_package_path = ERROR_SUCCESS == MsiGetProductInfoW(GUID_product_string, INSTALLPROPERTY_LOCALPACKAGE, nullptr, &package_path_size); !has_package_path)
|
||||
{
|
||||
return package_path;
|
||||
}
|
||||
|
||||
package_path = std::wstring(++package_path_size, L'\0');
|
||||
if (const bool got_package_path = ERROR_SUCCESS == MsiGetProductInfoW(GUID_product_string, INSTALLPROPERTY_LOCALPACKAGE, package_path.data(), &package_path_size); !got_package_path)
|
||||
{
|
||||
package_path = {};
|
||||
return package_path;
|
||||
}
|
||||
|
||||
package_path.resize(size(package_path) - 1); // trim additional \0 which we got from MsiGetProductInfoW
|
||||
|
||||
return package_path;
|
||||
}
|
||||
|
||||
bool offer_msi_uninstallation(const notifications::strings& strings)
|
||||
{
|
||||
const auto selection = SHMessageBoxCheckW(nullptr,
|
||||
strings.OFFER_UNINSTALL_MSI.c_str(),
|
||||
strings.OFFER_UNINSTALL_MSI_TITLE.c_str(),
|
||||
MB_ICONQUESTION | MB_YESNO,
|
||||
IDNO,
|
||||
DONT_SHOW_AGAIN_RECORD_REGISTRY_PATH);
|
||||
return selection == IDYES;
|
||||
}
|
||||
|
||||
bool uninstall_msi_version(const std::wstring& package_path, const notifications::strings& strings)
|
||||
{
|
||||
const auto uninstall_result = MsiInstallProductW(package_path.c_str(), L"REMOVE=ALL");
|
||||
if (ERROR_SUCCESS == uninstall_result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (auto system_message = get_last_error_message(uninstall_result); system_message.has_value())
|
||||
{
|
||||
try
|
||||
{
|
||||
::notifications::show_toast(*system_message, TOAST_TITLE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
MessageBoxW(nullptr, strings.UNINSTALLATION_UNKNOWN_ERROR.c_str(), strings.NOTIFICATION_TITLE.c_str(), MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<std::wstring> get_msi_package_installed_path()
|
||||
{
|
||||
constexpr size_t guid_length = 39;
|
||||
wchar_t product_ID[guid_length];
|
||||
if (const bool found = ERROR_SUCCESS == MsiEnumRelatedProductsW(POWER_TOYS_UPGRADE_CODE, 0, 0, product_ID); !found)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (const bool installed = INSTALLSTATE_DEFAULT == MsiQueryProductStateW(product_ID); !installed)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
DWORD buf_size = MAX_PATH;
|
||||
wchar_t buf[MAX_PATH];
|
||||
if (ERROR_SUCCESS == MsiGetProductInfoW(product_ID, INSTALLPROPERTY_INSTALLLOCATION, buf, &buf_size) && buf_size)
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
|
||||
DWORD package_path_size = 0;
|
||||
|
||||
if (ERROR_SUCCESS != MsiGetProductInfoW(product_ID, INSTALLPROPERTY_LOCALPACKAGE, nullptr, &package_path_size))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
std::wstring package_path(++package_path_size, L'\0');
|
||||
|
||||
if (ERROR_SUCCESS != MsiGetProductInfoW(product_ID, INSTALLPROPERTY_LOCALPACKAGE, package_path.data(), &package_path_size))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
package_path.resize(size(package_path) - 1); // trim additional \0 which we got from MsiGetProductInfoW
|
||||
|
||||
wchar_t path[MAX_PATH];
|
||||
DWORD path_size = MAX_PATH;
|
||||
MsiGetComponentPathW(product_ID, POWERTOYS_EXE_COMPONENT, path, &path_size);
|
||||
if (!path_size)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
PathCchRemoveFileSpec(path, path_size);
|
||||
return path;
|
||||
}
|
||||
|
||||
std::optional<VersionHelper> get_installed_powertoys_version()
|
||||
{
|
||||
auto installed_path = get_msi_package_installed_path();
|
||||
if (!installed_path)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
*installed_path += L"\\PowerToys.exe";
|
||||
|
||||
// Get the version information for the file requested
|
||||
const DWORD fvSize = GetFileVersionInfoSizeW(installed_path->c_str(), nullptr);
|
||||
if (!fvSize)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto pbVersionInfo = std::make_unique<BYTE[]>(fvSize);
|
||||
|
||||
if (!GetFileVersionInfoW(installed_path->c_str(), 0, fvSize, pbVersionInfo.get()))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
VS_FIXEDFILEINFO* fileInfo = nullptr;
|
||||
UINT fileInfoLen = 0;
|
||||
if (!VerQueryValueW(pbVersionInfo.get(), L"\\", reinterpret_cast<LPVOID*>(&fileInfo), &fileInfoLen))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return VersionHelper{ (fileInfo->dwFileVersionMS >> 16) & 0xffff,
|
||||
(fileInfo->dwFileVersionMS >> 0) & 0xffff,
|
||||
(fileInfo->dwFileVersionLS >> 16) & 0xffff };
|
||||
}
|
||||
|
||||
std::future<bool> uninstall_previous_msix_version_async()
|
||||
{
|
||||
winrt::Windows::Management::Deployment::PackageManager package_manager;
|
||||
|
@ -192,9 +43,4 @@ namespace updating
|
|||
}
|
||||
co_return false;
|
||||
}
|
||||
|
||||
bool is_1809_or_older()
|
||||
{
|
||||
return !Is19H1OrHigher();
|
||||
}
|
||||
}
|
|
@ -4,18 +4,9 @@
|
|||
#include <optional>
|
||||
#include <future>
|
||||
|
||||
#include "notifications.h"
|
||||
#include <common/version/helper.h>
|
||||
|
||||
namespace updating
|
||||
{
|
||||
std::wstring get_msi_package_path();
|
||||
bool uninstall_msi_version(const std::wstring& package_path, const notifications::strings&);
|
||||
bool offer_msi_uninstallation(const notifications::strings&);
|
||||
std::optional<std::wstring> get_msi_package_installed_path();
|
||||
|
||||
std::optional<VersionHelper> get_installed_powertoys_version();
|
||||
std::future<bool> uninstall_previous_msix_version_async();
|
||||
|
||||
bool is_1809_or_older();
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include "notifications.h"
|
||||
|
||||
#include <common/notifications/notifications.h>
|
||||
|
||||
#include "updating.h"
|
||||
|
||||
#include <common/version/helper.h>
|
||||
#include <common/version/version.h>
|
||||
|
||||
namespace updating
|
||||
{
|
||||
namespace notifications
|
||||
{
|
||||
using namespace ::notifications;
|
||||
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" -> ";
|
||||
current_version_to_next_version += info.version.toWstring();
|
||||
return current_version_to_next_version;
|
||||
}
|
||||
|
||||
void show_new_version_available(const new_version_download_info& info, 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;
|
||||
contents += L'\n';
|
||||
contents += current_version_to_next_version(info);
|
||||
|
||||
show_toast_with_activations(std::move(contents),
|
||||
strings.NOTIFICATION_TITLE,
|
||||
{},
|
||||
{ link_button{ strings.GITHUB_NEW_VERSION_UPDATE_NOW,
|
||||
L"powertoys://update_now/" },
|
||||
link_button{ strings.GITHUB_NEW_VERSION_MORE_INFO,
|
||||
L"powertoys://open_settings/" } },
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
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::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,
|
||||
{},
|
||||
std::move(actions),
|
||||
std::move(toast_params));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace updating
|
||||
{
|
||||
struct new_version_download_info;
|
||||
|
||||
namespace notifications
|
||||
{
|
||||
struct strings
|
||||
{
|
||||
std::wstring GITHUB_NEW_VERSION_AVAILABLE;
|
||||
std::wstring GITHUB_NEW_VERSION_MORE_INFO;
|
||||
std::wstring GITHUB_NEW_VERSION_UPDATE_NOW;
|
||||
|
||||
std::wstring OFFER_UNINSTALL_MSI;
|
||||
std::wstring OFFER_UNINSTALL_MSI_TITLE;
|
||||
|
||||
std::wstring NOTIFICATION_TITLE;
|
||||
|
||||
std::wstring UNINSTALLATION_UNKNOWN_ERROR;
|
||||
};
|
||||
|
||||
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 \
|
||||
{ \
|
||||
.GITHUB_NEW_VERSION_AVAILABLE = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_AVAILABLE), \
|
||||
.GITHUB_NEW_VERSION_MORE_INFO = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_MORE_INFO), \
|
||||
.GITHUB_NEW_VERSION_UPDATE_NOW = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_NOW), \
|
||||
.OFFER_UNINSTALL_MSI = GET_RESOURCE_STRING(IDS_OFFER_UNINSTALL_MSI), \
|
||||
.OFFER_UNINSTALL_MSI_TITLE = GET_RESOURCE_STRING(IDS_OFFER_UNINSTALL_MSI_TITLE), \
|
||||
.NOTIFICATION_TITLE = GET_RESOURCE_STRING(IDS_TOAST_TITLE), \
|
||||
.UNINSTALLATION_UNKNOWN_ERROR = GET_RESOURCE_STRING(IDS_UNINSTALLATION_UNKNOWN_ERROR) \
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include <common/utils/HttpClient.h>
|
||||
#include <common/version/version.h>
|
||||
#include <common/version/helper.h>
|
||||
|
||||
#include "http_client.h"
|
||||
#include "notifications.h"
|
||||
#include "updating.h"
|
||||
|
||||
#include <common/notifications/notifications.h>
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
#include <common/utils/json.h>
|
||||
|
||||
|
@ -76,7 +74,7 @@ namespace updating
|
|||
throw std::runtime_error("Release object doesn't have the required asset");
|
||||
}
|
||||
|
||||
std::future<nonstd::expected<github_version_info, std::wstring>> get_github_version_info_async(const notifications::strings& strings, const bool prerelease)
|
||||
std::future<nonstd::expected<github_version_info, std::wstring>> get_github_version_info_async(const bool prerelease)
|
||||
{
|
||||
// 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)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <winrt/Windows.Foundation.h>
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "notifications.h"
|
||||
#include <common/version/helper.h>
|
||||
|
||||
namespace updating
|
||||
|
@ -28,7 +27,7 @@ namespace updating
|
|||
|
||||
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<nonstd::expected<github_version_info, std::wstring>> get_github_version_info_async(const notifications::strings& strings, const bool prerelease = false);
|
||||
std::future<nonstd::expected<github_version_info, std::wstring>> get_github_version_info_async(const bool prerelease = false);
|
||||
|
||||
// non-localized
|
||||
constexpr inline std::wstring_view INSTALLER_FILENAME_PATTERN = L"powertoyssetup";
|
||||
|
|
|
@ -35,20 +35,13 @@
|
|||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dotnet_installation.h" />
|
||||
<ClInclude Include="http_client.h" />
|
||||
<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>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dotnet_installation.cpp" />
|
||||
<ClCompile Include="http_client.cpp" />
|
||||
<ClCompile Include="installer.cpp" />
|
||||
<ClCompile Include="notifications.cpp" />
|
||||
<ClCompile Include="updating.cpp" />
|
||||
<ClCompile Include="updateState.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
|
@ -56,9 +49,6 @@
|
|||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\notifications\notifications.vcxproj">
|
||||
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SettingsAPI\SetttingsAPI.vcxproj">
|
||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -21,21 +21,15 @@
|
|||
<ClInclude Include="updating.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="http_client.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dotnet_installation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="notifications.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="installer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="winstore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="updateState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
|
@ -44,18 +38,12 @@
|
|||
<ClCompile Include="updating.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="http_client.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dotnet_installation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="notifications.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="installer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="updateState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
79
src/common/utils/HttpClient.h
Normal file
79
src/common/utils/HttpClient.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.Web.Http.h>
|
||||
#include <winrt/Windows.Web.Http.Headers.h>
|
||||
namespace http
|
||||
{
|
||||
using namespace winrt::Windows::Web::Http;
|
||||
namespace storage = winrt::Windows::Storage;
|
||||
|
||||
const inline wchar_t USER_AGENT[] = L"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
|
||||
|
||||
class HttpClient
|
||||
{
|
||||
public:
|
||||
HttpClient()
|
||||
{
|
||||
auto headers = m_client.DefaultRequestHeaders();
|
||||
headers.UserAgent().TryParseAdd(USER_AGENT);
|
||||
}
|
||||
|
||||
std::future<std::wstring> request(const winrt::Windows::Foundation::Uri& url)
|
||||
{
|
||||
auto response = co_await m_client.GetAsync(url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
auto body = co_await response.Content().ReadAsStringAsync();
|
||||
co_return std::wstring(body);
|
||||
}
|
||||
|
||||
std::future<void> download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFilePath)
|
||||
{
|
||||
auto response = co_await m_client.GetAsync(url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
auto file_stream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(dstFilePath.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
co_await response.Content().WriteToStreamAsync(file_stream);
|
||||
file_stream.Close();
|
||||
}
|
||||
|
||||
std::future<void> download(const winrt::Windows::Foundation::Uri& url, const std::wstring& dstFilePath, const std::function<void(float)>& progressUpdateCallback)
|
||||
{
|
||||
auto response = co_await m_client.GetAsync(url, HttpCompletionOption::ResponseHeadersRead);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
uint64_t totalBytes = response.Content().Headers().ContentLength().GetUInt64();
|
||||
auto contentStream = co_await response.Content().ReadAsInputStreamAsync();
|
||||
|
||||
uint64_t totalBytesRead = 0;
|
||||
storage::Streams::Buffer buffer(8192);
|
||||
auto fileStream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(dstFilePath.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
|
||||
co_await contentStream.ReadAsync(buffer, buffer.Capacity(), storage::Streams::InputStreamOptions::None);
|
||||
while (buffer.Length() > 0)
|
||||
{
|
||||
co_await fileStream.WriteAsync(buffer);
|
||||
totalBytesRead += buffer.Length();
|
||||
if (progressUpdateCallback)
|
||||
{
|
||||
float percentage = (float)totalBytesRead / totalBytes;
|
||||
progressUpdateCallback(percentage);
|
||||
}
|
||||
|
||||
co_await contentStream.ReadAsync(buffer, buffer.Capacity(), storage::Streams::InputStreamOptions::None);
|
||||
}
|
||||
|
||||
if (progressUpdateCallback)
|
||||
{
|
||||
progressUpdateCallback(1);
|
||||
}
|
||||
|
||||
fileStream.Close();
|
||||
contentStream.Close();
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::Windows::Web::Http::HttpClient m_client;
|
||||
};
|
||||
}
|
95
src/common/utils/MsiUtils.h
Normal file
95
src/common/utils/MsiUtils.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#include <pathcch.h>
|
||||
#include <Msi.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace // Strings in this namespace should not be localized
|
||||
{
|
||||
const inline wchar_t POWER_TOYS_UPGRADE_CODE[] = L"{42B84BF7-5FBF-473B-9C8B-049DC16F7708}";
|
||||
const inline wchar_t POWERTOYS_EXE_COMPONENT[] = L"{A2C66D91-3485-4D00-B04D-91844E6B345B}";
|
||||
}
|
||||
|
||||
std::optional<std::wstring> GetMsiPackageInstalledPath()
|
||||
{
|
||||
constexpr size_t guid_length = 39;
|
||||
wchar_t product_ID[guid_length];
|
||||
if (const bool found = ERROR_SUCCESS == MsiEnumRelatedProductsW(POWER_TOYS_UPGRADE_CODE, 0, 0, product_ID); !found)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (const bool installed = INSTALLSTATE_DEFAULT == MsiQueryProductStateW(product_ID); !installed)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
DWORD buf_size = MAX_PATH;
|
||||
wchar_t buf[MAX_PATH];
|
||||
if (ERROR_SUCCESS == MsiGetProductInfoW(product_ID, INSTALLPROPERTY_INSTALLLOCATION, buf, &buf_size) && buf_size)
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
|
||||
DWORD package_path_size = 0;
|
||||
|
||||
if (ERROR_SUCCESS != MsiGetProductInfoW(product_ID, INSTALLPROPERTY_LOCALPACKAGE, nullptr, &package_path_size))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
std::wstring package_path(++package_path_size, L'\0');
|
||||
|
||||
if (ERROR_SUCCESS != MsiGetProductInfoW(product_ID, INSTALLPROPERTY_LOCALPACKAGE, package_path.data(), &package_path_size))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
package_path.resize(size(package_path) - 1); // trim additional \0 which we got from MsiGetProductInfoW
|
||||
|
||||
wchar_t path[MAX_PATH];
|
||||
DWORD path_size = MAX_PATH;
|
||||
MsiGetComponentPathW(product_ID, POWERTOYS_EXE_COMPONENT, path, &path_size);
|
||||
if (!path_size)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
PathCchRemoveFileSpec(path, path_size);
|
||||
return path;
|
||||
}
|
||||
|
||||
std::wstring GetMsiPackagePath()
|
||||
{
|
||||
std::wstring package_path;
|
||||
wchar_t GUID_product_string[39];
|
||||
if (const bool found = ERROR_SUCCESS == MsiEnumRelatedProductsW(POWER_TOYS_UPGRADE_CODE, 0, 0, GUID_product_string); !found)
|
||||
{
|
||||
return package_path;
|
||||
}
|
||||
|
||||
if (const bool installed = INSTALLSTATE_DEFAULT == MsiQueryProductStateW(GUID_product_string); !installed)
|
||||
{
|
||||
return package_path;
|
||||
}
|
||||
|
||||
DWORD package_path_size = 0;
|
||||
|
||||
if (const bool has_package_path = ERROR_SUCCESS == MsiGetProductInfoW(GUID_product_string, INSTALLPROPERTY_LOCALPACKAGE, nullptr, &package_path_size); !has_package_path)
|
||||
{
|
||||
return package_path;
|
||||
}
|
||||
|
||||
package_path = std::wstring(++package_path_size, L'\0');
|
||||
if (const bool got_package_path = ERROR_SUCCESS == MsiGetProductInfoW(GUID_product_string, INSTALLPROPERTY_LOCALPACKAGE, package_path.data(), &package_path_size); !got_package_path)
|
||||
{
|
||||
package_path = {};
|
||||
return package_path;
|
||||
}
|
||||
|
||||
package_path.resize(size(package_path) - 1); // trim additional \0 which we got from MsiGetProductInfoW
|
||||
|
||||
return package_path;
|
||||
}
|
|
@ -5,6 +5,9 @@
|
|||
#include <shellapi.h>
|
||||
#include <sddl.h>
|
||||
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
#include <string>
|
||||
#include <common/logger/logger.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
|
|
9
src/runner/ActionRunnerUtils.h
Normal file
9
src/runner/ActionRunnerUtils.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
namespace cmdArg
|
||||
{
|
||||
const inline wchar_t* RUN_NONELEVATED = L"-run-non-elevated";
|
||||
}
|
|
@ -97,9 +97,6 @@
|
|||
<data name="GITHUB_NEW_VERSION_UPDATE_NOW" xml:space="preserve">
|
||||
<value>Update now</value>
|
||||
</data>
|
||||
<data name="UNINSTALLATION_UNKNOWN_ERROR" xml:space="preserve">
|
||||
<value>Error: please uninstall the previous version of PowerToys manually.</value>
|
||||
</data>
|
||||
<data name="GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT" xml:space="preserve">
|
||||
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||
</data>
|
||||
|
@ -109,12 +106,6 @@
|
|||
<data name="TOAST_TITLE" xml:space="preserve">
|
||||
<value>PowerToys Update</value>
|
||||
</data>
|
||||
<data name="OFFER_UNINSTALL_MSI" xml:space="preserve">
|
||||
<value>We've detected a previous installation of PowerToys. Would you like to remove it?</value>
|
||||
</data>
|
||||
<data name="OFFER_UNINSTALL_MSI_TITLE" xml:space="preserve">
|
||||
<value>PowerToys: uninstall previous version?</value>
|
||||
</data>
|
||||
<data name="SETTINGS_MENU_TEXT" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
|
|
|
@ -2,63 +2,101 @@
|
|||
|
||||
#include "Generated Files/resource.h"
|
||||
|
||||
#include "action_runner_utils.h"
|
||||
#include "ActionRunnerUtils.h"
|
||||
#include "general_settings.h"
|
||||
#include "update_utils.h"
|
||||
#include "UpdateUtils.h"
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
#include <common/notifications/notifications.h>
|
||||
#include <common/updating/installer.h>
|
||||
#include <common/updating/http_client.h>
|
||||
#include <common/updating/updating.h>
|
||||
#include <common/updating/updateState.h>
|
||||
#include <common/utils/HttpClient.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/timeutil.h>
|
||||
|
||||
auto Strings = create_notifications_strings();
|
||||
#include <common/version/version.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int64_t UPDATE_CHECK_INTERVAL_MINUTES = 60 * 24;
|
||||
constexpr int64_t UPDATE_CHECK_AFTER_FAILED_INTERVAL_MINUTES = 60 * 2;
|
||||
}
|
||||
using namespace notifications;
|
||||
using namespace updating;
|
||||
|
||||
bool start_msi_uninstallation_sequence()
|
||||
std::wstring CurrentVersionToNextVersion(const new_version_download_info& info)
|
||||
{
|
||||
const auto package_path = updating::get_msi_package_path();
|
||||
auto result = VersionHelper{ VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION }.toWstring();
|
||||
result += L" -> ";
|
||||
result += info.version.toWstring();
|
||||
return result;
|
||||
}
|
||||
|
||||
if (package_path.empty())
|
||||
{
|
||||
// No MSI version detected
|
||||
return true;
|
||||
}
|
||||
void ShowNewVersionAvailable(const new_version_download_info& info)
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
if (!updating::offer_msi_uninstallation(Strings))
|
||||
{
|
||||
// User declined to uninstall or opted for "Don't show again"
|
||||
return false;
|
||||
}
|
||||
auto sei = launch_action_runner(L"-uninstall_msi");
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||
std::wstring contents = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_AVAILABLE);
|
||||
contents += L'\n';
|
||||
contents += CurrentVersionToNextVersion(info);
|
||||
|
||||
WaitForSingleObject(sei.hProcess, INFINITE);
|
||||
DWORD exit_code = 0;
|
||||
GetExitCodeProcess(sei.hProcess, &exit_code);
|
||||
CloseHandle(sei.hProcess);
|
||||
return exit_code == 0;
|
||||
show_toast_with_activations(std::move(contents),
|
||||
GET_RESOURCE_STRING(IDS_TOAST_TITLE),
|
||||
{},
|
||||
{ link_button{ GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_NOW),
|
||||
L"powertoys://update_now/" },
|
||||
link_button{ GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_MORE_INFO),
|
||||
L"powertoys://open_settings/" } },
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
void ShowOpenSettingsForUpdate()
|
||||
{
|
||||
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||
|
||||
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||
|
||||
std::vector<action_t> actions = {
|
||||
link_button{ GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_MORE_INFO),
|
||||
L"powertoys://open_settings/" },
|
||||
};
|
||||
show_toast_with_activations(GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_AVAILABLE),
|
||||
GET_RESOURCE_STRING(IDS_TOAST_TITLE),
|
||||
{},
|
||||
std::move(actions),
|
||||
std::move(toast_params));
|
||||
}
|
||||
|
||||
SHELLEXECUTEINFOW LaunchPowerToysUpdate(const wchar_t* cmdline)
|
||||
{
|
||||
std::wstring powertoysUpdaterPath;
|
||||
powertoysUpdaterPath = get_module_folderpath();
|
||||
|
||||
powertoysUpdaterPath += L"\\PowerToys.Update.exe";
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS };
|
||||
sei.lpFile = powertoysUpdaterPath.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpParameters = cmdline;
|
||||
ShellExecuteExW(&sei);
|
||||
return sei;
|
||||
}
|
||||
|
||||
using namespace updating;
|
||||
|
||||
bool could_be_costly_connection()
|
||||
bool IsMeteredConnection()
|
||||
{
|
||||
using namespace winrt::Windows::Networking::Connectivity;
|
||||
ConnectionProfile internetConnectionProfile = NetworkInformation::GetInternetConnectionProfile();
|
||||
return internetConnectionProfile && internetConnectionProfile.IsWwanConnectionProfile();
|
||||
}
|
||||
|
||||
void process_new_version_info(const github_version_info& version_info,
|
||||
UpdateState& state,
|
||||
const bool download_update,
|
||||
const bool show_notifications)
|
||||
void ProcessNewVersionInfo(const github_version_info& version_info,
|
||||
UpdateState& state,
|
||||
const bool download_update,
|
||||
const bool show_notifications)
|
||||
{
|
||||
state.githubUpdateLastCheckedDate.emplace(timeutil::now());
|
||||
if (std::holds_alternative<version_up_to_date>(version_info))
|
||||
|
@ -89,7 +127,7 @@ void process_new_version_info(const github_version_info& version_info,
|
|||
state.downloadedInstallerFilename = new_version_info.installer_filename;
|
||||
if (show_notifications)
|
||||
{
|
||||
notifications::show_new_version_available(new_version_info, Strings);
|
||||
ShowNewVersionAvailable(new_version_info);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -106,12 +144,12 @@ void process_new_version_info(const github_version_info& version_info,
|
|||
state.downloadedInstallerFilename = {};
|
||||
if (show_notifications)
|
||||
{
|
||||
notifications::show_open_settings_for_update(Strings);
|
||||
ShowOpenSettingsForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void periodic_update_worker()
|
||||
void PeriodicUpdateWorker()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -129,15 +167,15 @@ void periodic_update_worker()
|
|||
|
||||
std::this_thread::sleep_for(std::chrono::minutes{ sleep_minutes_till_next_update });
|
||||
|
||||
const bool download_update = !could_be_costly_connection() && get_general_settings().downloadUpdatesAutomatically;
|
||||
const bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
|
||||
bool version_info_obtained = false;
|
||||
try
|
||||
{
|
||||
const auto new_version_info = get_github_version_info_async(Strings).get();
|
||||
const auto new_version_info = get_github_version_info_async().get();
|
||||
if (new_version_info.has_value())
|
||||
{
|
||||
version_info_obtained = true;
|
||||
process_new_version_info(*new_version_info, state, download_update, true);
|
||||
ProcessNewVersionInfo(*new_version_info, state, download_update, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -162,27 +200,27 @@ void periodic_update_worker()
|
|||
}
|
||||
}
|
||||
|
||||
void check_for_updates_settings_callback()
|
||||
void CheckForUpdatesCallback()
|
||||
{
|
||||
Logger::trace(L"Check for updates callback invoked");
|
||||
auto state = UpdateState::read();
|
||||
try
|
||||
{
|
||||
auto new_version_info = get_github_version_info_async(Strings).get();
|
||||
auto new_version_info = get_github_version_info_async().get();
|
||||
if (!new_version_info)
|
||||
{
|
||||
// If we couldn't get a new version from github for some reason, assume we're up to date, but also log error
|
||||
new_version_info = version_up_to_date{};
|
||||
Logger::error(L"Couldn't obtain version info from github: {}", new_version_info.error());
|
||||
}
|
||||
const bool download_update = !could_be_costly_connection() && get_general_settings().downloadUpdatesAutomatically;
|
||||
process_new_version_info(*new_version_info, state, download_update, false);
|
||||
const bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
|
||||
ProcessNewVersionInfo(*new_version_info, state, download_update, false);
|
||||
UpdateState::store([&](UpdateState& v) {
|
||||
v = std::move(state);
|
||||
});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Logger::error("check_for_updates_settings_callback: error while processing version info");
|
||||
Logger::error("CheckForUpdatesCallback: error while processing version info");
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <common/updating/updating.h>
|
||||
|
||||
SHELLEXECUTEINFOW launch_action_runner(const wchar_t* cmdline);
|
||||
void PeriodicUpdateWorker();
|
||||
void CheckForUpdatesCallback();
|
||||
|
||||
namespace cmdArg
|
||||
{
|
||||
|
@ -16,8 +16,7 @@ namespace cmdArg
|
|||
const inline wchar_t* UPDATE_STAGE2_RESTART_PT = L"restart";
|
||||
const inline wchar_t* UPDATE_STAGE2_DONT_START_PT = L"dont_start";
|
||||
|
||||
const inline wchar_t* UNINSTALL_MSI = L"-uninstall_msi";
|
||||
const inline wchar_t* RUN_NONELEVATED = L"-run-non-elevated";
|
||||
|
||||
const inline wchar_t* UPDATE_REPORT_SUCCESS = L"-report_update_success";
|
||||
}
|
||||
|
||||
SHELLEXECUTEINFOW LaunchPowerToysUpdate(const wchar_t* cmdline);
|
|
@ -1,28 +0,0 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include "action_runner_utils.h"
|
||||
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/winstore/winstore.h>
|
||||
|
||||
SHELLEXECUTEINFOW launch_action_runner(const wchar_t* cmdline)
|
||||
{
|
||||
std::wstring action_runner_path;
|
||||
if (winstore::running_as_packaged())
|
||||
{
|
||||
action_runner_path = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation().Path();
|
||||
}
|
||||
else
|
||||
{
|
||||
action_runner_path = get_module_folderpath();
|
||||
}
|
||||
|
||||
action_runner_path += L"\\PowerToys.ActionRunner.exe";
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS };
|
||||
sei.lpFile = action_runner_path.c_str();
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpParameters = cmdline;
|
||||
ShellExecuteExW(&sei);
|
||||
return sei;
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
#include "powertoy_module.h"
|
||||
#include <common/themes/windows_colors.h>
|
||||
#include <common/winstore/winstore.h>
|
||||
|
||||
#include "trace.h"
|
||||
#include <common/utils/elevation.h>
|
||||
|
@ -22,7 +21,6 @@ json::JsonObject GeneralSettings::to_json()
|
|||
{
|
||||
json::JsonObject result;
|
||||
|
||||
result.SetNamedValue(L"packaged", json::value(isPackaged));
|
||||
result.SetNamedValue(L"startup", json::value(isStartupEnabled));
|
||||
if (!startupDisabledReason.empty())
|
||||
{
|
||||
|
@ -65,7 +63,6 @@ GeneralSettings get_general_settings()
|
|||
{
|
||||
const bool is_user_admin = check_user_is_admin();
|
||||
GeneralSettings settings{
|
||||
.isPackaged = winstore::running_as_packaged(),
|
||||
.isElevated = is_process_elevated(),
|
||||
.isRunElevated = run_as_elevated,
|
||||
.isAdmin = is_user_admin,
|
||||
|
@ -75,31 +72,7 @@ GeneralSettings get_general_settings()
|
|||
.powerToysVersion = get_product_version()
|
||||
};
|
||||
|
||||
if (winstore::running_as_packaged())
|
||||
{
|
||||
const auto task_state = winstore::get_startup_task_status_async().get();
|
||||
switch (task_state)
|
||||
{
|
||||
case winstore::StartupTaskState::Disabled:
|
||||
settings.isStartupEnabled = false;
|
||||
break;
|
||||
case winstore::StartupTaskState::Enabled:
|
||||
settings.isStartupEnabled = true;
|
||||
break;
|
||||
case winstore::StartupTaskState::DisabledByPolicy:
|
||||
settings.startupDisabledReason = GET_RESOURCE_STRING(IDS_STARTUP_DISABLED_BY_POLICY);
|
||||
settings.isStartupEnabled = false;
|
||||
break;
|
||||
case winstore::StartupTaskState::DisabledByUser:
|
||||
settings.startupDisabledReason = GET_RESOURCE_STRING(IDS_STARTUP_DISABLED_BY_USER);
|
||||
settings.isStartupEnabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.isStartupEnabled = is_auto_start_task_active_for_this_user();
|
||||
}
|
||||
settings.isStartupEnabled = is_auto_start_task_active_for_this_user();
|
||||
|
||||
for (auto& [name, powertoy] : modules())
|
||||
{
|
||||
|
@ -118,40 +91,33 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
|
|||
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean))
|
||||
{
|
||||
const bool startup = general_configs.GetNamedBoolean(L"startup");
|
||||
if (winstore::running_as_packaged())
|
||||
if (startup)
|
||||
{
|
||||
winstore::switch_startup_task_state_async(startup).wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startup)
|
||||
if (is_process_elevated())
|
||||
{
|
||||
if (is_process_elevated())
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
create_auto_start_task_for_this_user(general_configs.GetNamedBoolean(L"run_elevated", false));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_auto_start_task_active_for_this_user())
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
create_auto_start_task_for_this_user(false);
|
||||
|
||||
run_as_elevated = false;
|
||||
}
|
||||
else if (!general_configs.GetNamedBoolean(L"run_elevated", false))
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
create_auto_start_task_for_this_user(false);
|
||||
}
|
||||
}
|
||||
delete_auto_start_task_for_this_user();
|
||||
create_auto_start_task_for_this_user(general_configs.GetNamedBoolean(L"run_elevated", false));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
if (!is_auto_start_task_active_for_this_user())
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
create_auto_start_task_for_this_user(false);
|
||||
|
||||
run_as_elevated = false;
|
||||
}
|
||||
else if (!general_configs.GetNamedBoolean(L"run_elevated", false))
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
create_auto_start_task_for_this_user(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_auto_start_task_for_this_user();
|
||||
}
|
||||
}
|
||||
if (json::has(general_configs, L"enabled"))
|
||||
{
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
struct GeneralSettings
|
||||
{
|
||||
bool isPackaged;
|
||||
bool isStartupEnabled;
|
||||
std::wstring startupDisabledReason;
|
||||
std::map<std::wstring, bool> isModulesEnabledMap;
|
||||
|
|
|
@ -22,10 +22,9 @@
|
|||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/processApi.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/winstore/winstore.h>
|
||||
|
||||
#include "update_utils.h"
|
||||
#include "action_runner_utils.h"
|
||||
#include "UpdateUtils.h"
|
||||
#include "ActionRunnerUtils.h"
|
||||
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
|
@ -45,8 +44,6 @@
|
|||
#include <common/utils/window.h>
|
||||
#include <common/version/version.h>
|
||||
|
||||
extern updating::notifications::strings Strings;
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t PT_URI_PROTOCOL_SCHEME[] = L"powertoys://";
|
||||
|
@ -120,26 +117,15 @@ int runner(bool isProcessElevated, bool openSettings, bool openOobe)
|
|||
debug_verify_launcher_assets();
|
||||
|
||||
std::thread{ [] {
|
||||
periodic_update_worker();
|
||||
PeriodicUpdateWorker();
|
||||
} }.detach();
|
||||
|
||||
if (winstore::running_as_packaged())
|
||||
{
|
||||
std::thread{ [] {
|
||||
start_msi_uninstallation_sequence();
|
||||
} }.detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::thread{ [] {
|
||||
if (updating::uninstall_previous_msix_version_async().get())
|
||||
{
|
||||
notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L"PowerToys");
|
||||
}
|
||||
} }.detach();
|
||||
}
|
||||
|
||||
notifications::register_background_toast_handler();
|
||||
std::thread{ [] {
|
||||
if (updating::uninstall_previous_msix_version_async().get())
|
||||
{
|
||||
notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L"PowerToys");
|
||||
}
|
||||
} }.detach();
|
||||
|
||||
chdir_current_executable();
|
||||
// Load Powertoys DLLs
|
||||
|
@ -258,7 +244,7 @@ toast_notification_handler_result toast_notification_handler(const std::wstring_
|
|||
else if (param.starts_with(update_now))
|
||||
{
|
||||
std::wstring args{ cmdArg::UPDATE_NOW_LAUNCH_STAGE1 };
|
||||
launch_action_runner(args.c_str());
|
||||
LaunchPowerToysUpdate(args.c_str());
|
||||
return toast_notification_handler_result::exit_success;
|
||||
}
|
||||
else if (param == couldnt_toggle_powerpreview_modules_disable)
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\interop\two_way_pipe_message_ipc.cpp" />
|
||||
<ClCompile Include="action_runner_utils.cpp" />
|
||||
<ClCompile Include="auto_start_helper.cpp" />
|
||||
<ClCompile Include="CentralizedHotkeys.cpp" />
|
||||
<ClCompile Include="general_settings.cpp" />
|
||||
|
@ -62,17 +61,17 @@
|
|||
<ClCompile Include="trace.cpp" />
|
||||
<ClCompile Include="tray_icon.cpp" />
|
||||
<ClCompile Include="unhandled_exception_handler.cpp" />
|
||||
<ClCompile Include="update_utils.cpp" />
|
||||
<ClCompile Include="UpdateUtils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="action_runner_utils.h" />
|
||||
<ClInclude Include="ActionRunnerUtils.h" />
|
||||
<ClInclude Include="auto_start_helper.h" />
|
||||
<ClInclude Include="CentralizedHotkeys.h" />
|
||||
<ClInclude Include="general_settings.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="centralized_kb_hook.h" />
|
||||
<ClInclude Include="settings_telemetry.h" />
|
||||
<ClInclude Include="update_utils.h" />
|
||||
<ClInclude Include="UpdateUtils.h" />
|
||||
<ClInclude Include="powertoy_module.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="restart_elevated.h" />
|
||||
|
@ -111,9 +110,6 @@
|
|||
<ProjectReference Include="..\common\updating\updating.vcxproj">
|
||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\WinStore\Winstore.vcxproj">
|
||||
<Project>{c502a854-53ac-4ebb-8dc0-e4af2191e4f6}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
@ -27,10 +27,7 @@
|
|||
<ClCompile Include="restart_elevated.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="update_utils.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="action_runner_utils.cpp">
|
||||
<ClCompile Include="UpdateUtils.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="centralized_kb_hook.cpp">
|
||||
|
@ -72,10 +69,10 @@
|
|||
<ClInclude Include="restart_elevated.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="update_utils.h">
|
||||
<ClInclude Include="UpdateUtils.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="action_runner_utils.h">
|
||||
<ClInclude Include="ActionRunnerUtils.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "tray_icon.h"
|
||||
#include "general_settings.h"
|
||||
#include "restart_elevated.h"
|
||||
#include "update_utils.h"
|
||||
#include "UpdateUtils.h"
|
||||
#include "centralized_kb_hook.h"
|
||||
|
||||
#include <common/utils/json.h>
|
||||
|
@ -84,7 +84,7 @@ std::optional<std::wstring> dispatch_json_action_to_module(const json::JsonObjec
|
|||
}
|
||||
else if (action == L"check_for_updates")
|
||||
{
|
||||
check_for_updates_settings_callback();
|
||||
CheckForUpdatesCallback();
|
||||
}
|
||||
else if (action == L"request_update_state_date")
|
||||
{
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <common/updating/updating.h>
|
||||
|
||||
bool start_msi_uninstallation_sequence();
|
||||
void periodic_update_worker();
|
||||
void check_for_updates_settings_callback();
|
|
@ -13,10 +13,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
{
|
||||
public class GeneralSettings : ISettingsConfig
|
||||
{
|
||||
// Gets or sets a value indicating whether packaged.
|
||||
[JsonPropertyName("packaged")]
|
||||
public bool Packaged { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether run powertoys on start-up.
|
||||
[JsonPropertyName("startup")]
|
||||
public bool Startup { get; set; }
|
||||
|
@ -57,7 +53,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
[SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Any error from calling interop code should not prevent the program from loading.")]
|
||||
public GeneralSettings()
|
||||
{
|
||||
Packaged = false;
|
||||
Startup = false;
|
||||
IsAdmin = false;
|
||||
IsElevated = false;
|
||||
|
|
|
@ -112,7 +112,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private bool _packaged;
|
||||
private bool _startup;
|
||||
private bool _isElevated;
|
||||
private bool _runElevated;
|
||||
|
@ -130,24 +129,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
private bool _isNewVersionDownloading;
|
||||
private bool _isNewVersionChecked;
|
||||
|
||||
// Gets or sets a value indicating whether packaged.
|
||||
public bool Packaged
|
||||
{
|
||||
get
|
||||
{
|
||||
return _packaged;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_packaged != value)
|
||||
{
|
||||
_packaged = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets or sets a value indicating whether run powertoys on start-up.
|
||||
public bool Startup
|
||||
{
|
||||
|
|
|
@ -61,7 +61,6 @@ namespace ViewModelTests
|
|||
|
||||
// Verify that the old settings persisted
|
||||
Assert.AreEqual(originalGeneralSettings.AutoDownloadUpdates, viewModel.AutoDownloadUpdates);
|
||||
Assert.AreEqual(originalGeneralSettings.Packaged, viewModel.Packaged);
|
||||
Assert.AreEqual(originalGeneralSettings.PowertoysVersion, viewModel.PowerToysVersion);
|
||||
Assert.AreEqual(originalGeneralSettings.RunElevated, viewModel.RunElevated);
|
||||
Assert.AreEqual(originalGeneralSettings.Startup, viewModel.Startup);
|
||||
|
|
Loading…
Reference in a new issue