mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 09:28:03 +08:00
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'
|
to: 'Build_Output'
|
||||||
include:
|
include:
|
||||||
- 'PowerToys.ActionRunner.exe'
|
- 'PowerToys.ActionRunner.exe'
|
||||||
|
- 'PowerToys.Update.exe'
|
||||||
- 'BackgroundActivatorDLL.dll'
|
- 'BackgroundActivatorDLL.dll'
|
||||||
- 'Notifications.dll'
|
- 'Notifications.dll'
|
||||||
- 'os-detection.dll'
|
- 'os-detection.dll'
|
||||||
|
@ -272,8 +272,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interop", "interop", "{5A78
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "log", "log", "{E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "log", "log", "{E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}"
|
||||||
EndProject
|
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}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "COMUtils", "src\common\COMUtils\COMUtils.vcxproj", "{7319089E-46D6-4400-BC65-E39BDF1416EE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Display", "src\common\Display\Display.vcxproj", "{CABA8DFB-823B-4BF2-93AC-3F31984150D9}"
|
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\EventLocker.h = src\common\utils\EventLocker.h
|
||||||
src\common\utils\EventWaiter.h = src\common\utils\EventWaiter.h
|
src\common\utils\EventWaiter.h = src\common\utils\EventWaiter.h
|
||||||
src\common\utils\exec.h = src\common\utils\exec.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\json.h = src\common\utils\json.h
|
||||||
src\common\utils\logger_helper.h = src\common\utils\logger_helper.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\os-detect.h = src\common\utils\os-detect.h
|
||||||
src\common\utils\process_path.h = src\common\utils\process_path.h
|
src\common\utils\process_path.h = src\common\utils\process_path.h
|
||||||
src\common\utils\ProcessWaiter.h = src\common\utils\ProcessWaiter.h
|
src\common\utils\ProcessWaiter.h = src\common\utils\ProcessWaiter.h
|
||||||
@ -345,6 +345,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuideModuleInterfac
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuide", "src\modules\ShortcutGuide\ShortcutGuide\ShortcutGuide.vcxproj", "{2EDB3EB4-FA92-4BFF-B2D8-566584837231}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuide", "src\modules\ShortcutGuide\ShortcutGuide\ShortcutGuide.vcxproj", "{2EDB3EB4-FA92-4BFF-B2D8-566584837231}"
|
||||||
EndProject
|
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}"
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
@ -623,10 +625,6 @@ Global
|
|||||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.Build.0 = Debug|x64
|
{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.ActiveCfg = Release|x64
|
||||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
{7319089E-46D6-4400-BC65-E39BDF1416EE}.Debug|x64.Build.0 = Debug|x64
|
{7319089E-46D6-4400-BC65-E39BDF1416EE}.Debug|x64.Build.0 = Debug|x64
|
||||||
{7319089E-46D6-4400-BC65-E39BDF1416EE}.Release|x64.ActiveCfg = Release|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}.Debug|x64.Build.0 = Debug|x64
|
||||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.ActiveCfg = Release|x64
|
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.ActiveCfg = Release|x64
|
||||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Debug|x64.Build.0 = 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.ActiveCfg = Release|x64
|
||||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}.Release|x64.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Debug|x64.Build.0 = 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.ActiveCfg = Release|x64
|
||||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1}.Release|x64.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Debug|x64.Build.0 = Debug|x64
|
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Debug|x64.Build.0 = Debug|x64
|
||||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81}.Release|x64.ActiveCfg = Release|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}.Debug|x64.Build.0 = Debug|x64
|
||||||
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.ActiveCfg = Release|x64
|
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.ActiveCfg = Release|x64
|
||||||
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
{5043CECE-E6A7-4867-9CBE-02D27D83747A}.Debug|x64.Build.0 = Debug|x64
|
{5043CECE-E6A7-4867-9CBE-02D27D83747A}.Debug|x64.Build.0 = Debug|x64
|
||||||
{5043CECE-E6A7-4867-9CBE-02D27D83747A}.Release|x64.ActiveCfg = Release|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}
|
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||||
{5A7818A8-109C-4E1C-850D-1A654E234B0E} = {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}
|
{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}
|
{7319089E-46D6-4400-BC65-E39BDF1416EE} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||||
{CABA8DFB-823B-4BF2-93AC-3F31984150D9} = {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}
|
{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}
|
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {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}
|
{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}
|
{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}
|
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||||
{D940E07F-532C-4FF3-883F-790DA014F19A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
{D940E07F-532C-4FF3-883F-790DA014F19A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||||
{106CBECA-0701-4FC3-838C-9DF816A19AE2} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{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
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 16.0.30320.27
|
VisualStudioVersion = 16.0.30320.27
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
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}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bootstrapper", "bootstrapper\bootstrapper.vcxproj", "{D194E3AA-F824-4CA9-9A58-034DD6B7D022}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "..\..\src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
|
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
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetttingsAPI", "..\..\src\common\SettingsAPI\SetttingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetttingsAPI", "..\..\src\common\SettingsAPI\SetttingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
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.ActiveCfg = Debug|x64
|
||||||
{D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.Build.0 = Debug|x64
|
{D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.Build.0 = Debug|x64
|
||||||
{D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Release|x64.ActiveCfg = Release|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}.Debug|x64.Build.0 = Debug|x64
|
||||||
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.ActiveCfg = Release|x64
|
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.ActiveCfg = Release|x64
|
||||||
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include "dotnet_installation.h"
|
#include "DotnetInstallation.h"
|
||||||
#include "http_client.h"
|
|
||||||
|
|
||||||
#include "utils/exec.h"
|
|
||||||
#include "utils/winapi_error.h"
|
|
||||||
|
|
||||||
|
#include <common/utils/exec.h>
|
||||||
|
#include <common/utils/HttpClient.h>
|
||||||
|
#include <common/utils/winapi_error.h>
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace updating
|
namespace updating
|
@ -67,30 +67,9 @@
|
|||||||
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
||||||
<value>PowerToys installation error</value>
|
<value>PowerToys installation error</value>
|
||||||
</data>
|
</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">
|
<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>
|
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||||
</data>
|
</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">
|
<data name="INSTALLER_EXTRACT_ERROR" xml:space="preserve">
|
||||||
<value>Couldn't extract MSI installer.</value>
|
<value>Couldn't extract MSI installer.</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -2,23 +2,21 @@
|
|||||||
#include "Generated Files/resource.h"
|
#include "Generated Files/resource.h"
|
||||||
|
|
||||||
#include "RcResource.h"
|
#include "RcResource.h"
|
||||||
#include <common/updating/dotnet_installation.h>
|
#include <common/version/helper.h>
|
||||||
#include <common/updating/installer.h>
|
|
||||||
#include <common/updating/notifications.h>
|
|
||||||
#include <common/version/version.h>
|
#include <common/version/version.h>
|
||||||
#include <common/utils/appMutex.h>
|
#include <common/utils/appMutex.h>
|
||||||
#include <common/utils/elevation.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/processApi.h>
|
||||||
#include <common/utils/resources.h>
|
#include <common/utils/resources.h>
|
||||||
#include <common/utils/window.h>
|
#include <common/utils/window.h>
|
||||||
#include <common/utils/winapi_error.h>
|
#include <common/utils/winapi_error.h>
|
||||||
#include <common/SettingsAPI/settings_helpers.h>
|
#include <common/SettingsAPI/settings_helpers.h>
|
||||||
|
|
||||||
#include <runner/action_runner_utils.h>
|
#include "DotnetInstallation.h"
|
||||||
|
|
||||||
#include "progressbar_window.h"
|
#include "progressbar_window.h"
|
||||||
|
|
||||||
auto Strings = create_notifications_strings();
|
|
||||||
static bool g_Silent = false;
|
static bool g_Silent = false;
|
||||||
|
|
||||||
#define STR_HELPER(x) #x
|
#define STR_HELPER(x) #x
|
||||||
@ -95,7 +93,7 @@ void CleanupSettingsFromOlderVersions()
|
|||||||
spdlog::info("Old log settings file wasn't found");
|
spdlog::info("Old log settings file wasn't found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(...)
|
catch (...)
|
||||||
{
|
{
|
||||||
spdlog::error("Failed to cleanup old log settings");
|
spdlog::error("Failed to cleanup old log settings");
|
||||||
}
|
}
|
||||||
@ -117,6 +115,46 @@ void ShowMessageBoxError(const UINT messageId)
|
|||||||
ShowMessageBoxError(GET_RESOURCE_STRING(messageId).c_str());
|
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)
|
int Bootstrapper(HINSTANCE hInstance)
|
||||||
{
|
{
|
||||||
winrt::init_apartment();
|
winrt::init_apartment();
|
||||||
@ -234,7 +272,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||||||
const VersionHelper myVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
|
const VersionHelper myVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
|
||||||
|
|
||||||
// Do not support installing on Windows < 1903
|
// Do not support installing on Windows < 1903
|
||||||
if (updating::is_1809_or_older())
|
if (!Is19H1OrHigher())
|
||||||
{
|
{
|
||||||
ShowMessageBoxError(IDS_OLD_WINDOWS_ERROR);
|
ShowMessageBoxError(IDS_OLD_WINDOWS_ERROR);
|
||||||
spdlog::error("PowerToys {} requires at least Windows 1903 to run.", myVersion.toString());
|
spdlog::error("PowerToys {} requires at least Windows 1903 to run.", myVersion.toString());
|
||||||
@ -242,7 +280,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if there's a newer version installed
|
// 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)
|
if (installedVersion && *installedVersion >= myVersion)
|
||||||
{
|
{
|
||||||
spdlog::error(L"Detected a newer version {} vs {}", (*installedVersion).toWstring(), myVersion.toWstring());
|
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");
|
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())
|
if (!package_path.empty())
|
||||||
{
|
{
|
||||||
spdlog::debug(L"Existing MSI package path found: {}", package_path);
|
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");
|
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());
|
spdlog::error("Couldn't install the existing MSI package ({})", GetLastError());
|
||||||
ShowMessageBoxError(IDS_UNINSTALL_PREVIOUS_VERSION_ERROR);
|
ShowMessageBoxError(IDS_UNINSTALL_PREVIOUS_VERSION_ERROR);
|
||||||
@ -419,7 +457,7 @@ int Bootstrapper(HINSTANCE hInstance)
|
|||||||
if ((!noStartPT && !g_Silent) || startPT)
|
if ((!noStartPT && !g_Silent) || startPT)
|
||||||
{
|
{
|
||||||
spdlog::debug("Starting the newly installed PowerToys.exe");
|
spdlog::debug("Starting the newly installed PowerToys.exe");
|
||||||
auto newPTPath = updating::get_msi_package_installed_path();
|
auto newPTPath = GetMsiPackageInstalledPath();
|
||||||
if (!newPTPath)
|
if (!newPTPath)
|
||||||
{
|
{
|
||||||
spdlog::error("Couldn't determine new MSI package install location ({})", GetLastError());
|
spdlog::error("Couldn't determine new MSI package install location ({})", GetLastError());
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
<VCProjectVersion>16.0</VCProjectVersion>
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
<ProjectGuid>{D194E3AA-F824-4CA9-9A58-034DD6B7D022}</ProjectGuid>
|
<ProjectGuid>{D194E3AA-F824-4CA9-9A58-034DD6B7D022}</ProjectGuid>
|
||||||
<RootNamespace>bootstrapper</RootNamespace>
|
<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>
|
<ProjectName>bootstrapper</ProjectName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
@ -71,7 +73,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
@ -88,12 +90,12 @@
|
|||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
@ -106,11 +108,12 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="bootstrapper.cpp" />
|
<ClCompile Include="bootstrapper.cpp" />
|
||||||
|
<ClCompile Include="DotnetInstallation.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
@ -119,6 +122,7 @@
|
|||||||
<ClCompile Include="RcResource.cpp" />
|
<ClCompile Include="RcResource.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="DotnetInstallation.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="progressbar_window.h" />
|
<ClInclude Include="progressbar_window.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -133,8 +137,11 @@
|
|||||||
<Image Include="..\runner\svgs\icon.ico" />
|
<Image Include="..\runner\svgs\icon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\src\common\updating\updating.vcxproj">
|
<ProjectReference Include="..\..\..\src\common\SettingsAPI\SetttingsAPI.vcxproj">
|
||||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\..\src\common\version\version.vcxproj">
|
||||||
|
<Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\..\src\logging\logging.vcxproj">
|
<ProjectReference Include="..\..\..\src\logging\logging.vcxproj">
|
||||||
<Project>{7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f}</Project>
|
<Project>{7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f}</Project>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
|
|
||||||
|
#include <charconv>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -22,8 +23,10 @@
|
|||||||
#include <spdlog/sinks/null_sink.h>
|
#include <spdlog/sinks/null_sink.h>
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
|
||||||
|
#pragma warning(push, 0)
|
||||||
#include <winrt/base.h>
|
#include <winrt/base.h>
|
||||||
#include <winrt/Windows.Foundation.h>
|
#include <winrt/Windows.Foundation.h>
|
||||||
#include <winrt/Windows.Foundation.Collections.h>
|
#include <winrt/Windows.Foundation.Collections.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
#include <cxxopts.hpp>
|
#include <cxxopts.hpp>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include <common/updating/notifications.h>
|
|
||||||
#include <common/utils/window.h>
|
#include <common/utils/window.h>
|
||||||
|
|
||||||
#include "progressbar_window.h"
|
#include "progressbar_window.h"
|
||||||
|
@ -359,6 +359,9 @@
|
|||||||
<Component Id="PowerToys_ActionRunner_exe" Guid="626ABB17-16F0-4007-9A58-6998724A5E14" Win64="yes">
|
<Component Id="PowerToys_ActionRunner_exe" Guid="626ABB17-16F0-4007-9A58-6998724A5E14" Win64="yes">
|
||||||
<File Id="PowerToys.ActionRunner.exe" KeyPath="yes" Checksum="yes" />
|
<File Id="PowerToys.ActionRunner.exe" KeyPath="yes" Checksum="yes" />
|
||||||
</Component>
|
</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">
|
<Component Id="License_rtf" Guid="3E5AE43B-CFB4-449B-A346-94CAAFF3312E" Win64="yes">
|
||||||
<File Source="$(var.RepoDir)\installer\License.rtf" Id="License.rtf" KeyPath="yes" />
|
<File Source="$(var.RepoDir)\installer\License.rtf" Id="License.rtf" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
@ -869,6 +872,7 @@
|
|||||||
<ComponentRef Id="PowerToysStartMenuShortcut"/>
|
<ComponentRef Id="PowerToysStartMenuShortcut"/>
|
||||||
<ComponentRef Id="BackgroundActivator_dll" />
|
<ComponentRef Id="BackgroundActivator_dll" />
|
||||||
<ComponentRef Id="PowerToys_ActionRunner_exe" />
|
<ComponentRef Id="PowerToys_ActionRunner_exe" />
|
||||||
|
<ComponentRef Id="PowerToys_Update_exe" />
|
||||||
<ComponentRef Id="powertoys_toast_clsid" />
|
<ComponentRef Id="powertoys_toast_clsid" />
|
||||||
<ComponentRef Id="License_rtf" />
|
<ComponentRef Id="License_rtf" />
|
||||||
<ComponentRef Id="Notice_md" />
|
<ComponentRef Id="Notice_md" />
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <ProjectTelemetry.h>
|
#include <ProjectTelemetry.h>
|
||||||
|
|
||||||
|
#include "../../src/common/utils/MsiUtils.h"
|
||||||
#include "../../src/common/updating/installer.h"
|
#include "../../src/common/updating/installer.h"
|
||||||
#include "../../src/common/version/version.h"
|
#include "../../src/common/version/version.h"
|
||||||
|
|
||||||
@ -582,7 +583,7 @@ UINT __stdcall DetectPrevInstallPathCA(MSIHANDLE hInstall)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (auto install_path = updating::get_msi_package_installed_path())
|
if (auto install_path = GetMsiPackageInstalledPath())
|
||||||
{
|
{
|
||||||
MsiSetPropertyW(hInstall, L"INSTALLFOLDER", install_path->data());
|
MsiSetPropertyW(hInstall, L"INSTALLFOLDER", install_path->data());
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalLibraryDirectories>$(WIX)sdk\$(WixPlatformToolset)\lib\x64;$(SolutionDir)\packages\WiX.3.11.2\tools\sdk\vs2017\lib\x64;..\..\$(PlatformShortName)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
@ -64,28 +64,7 @@
|
|||||||
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
<data name="DOTNET_CORE_DOWNLOAD_FAILURE_TITLE" xml:space="preserve">
|
||||||
<value>PowerToys installation error</value>
|
<value>PowerToys installation error</value>
|
||||||
</data>
|
</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">
|
<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>
|
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
|
@ -11,12 +11,6 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string_view>
|
#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/elevation.h>
|
||||||
#include <common/utils/process_path.h>
|
#include <common/utils/process_path.h>
|
||||||
#include <common/utils/resources.h>
|
#include <common/utils/resources.h>
|
||||||
@ -28,214 +22,14 @@
|
|||||||
|
|
||||||
#include <winrt/Windows.ApplicationModel.h>
|
#include <winrt/Windows.ApplicationModel.h>
|
||||||
#include <winrt/Windows.Storage.h>
|
#include <winrt/Windows.Storage.h>
|
||||||
#include <Msi.h>
|
|
||||||
|
|
||||||
#include "../runner/tray_icon.h"
|
#include "../runner/tray_icon.h"
|
||||||
#include "../runner/action_runner_utils.h"
|
#include "../runner/ActionRunnerUtils.h"
|
||||||
|
|
||||||
auto Strings = create_notifications_strings();
|
|
||||||
|
|
||||||
using namespace cmdArg;
|
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;
|
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 WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||||
{
|
{
|
||||||
int nArgs = 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -41,15 +41,9 @@
|
|||||||
<ProjectReference Include="..\common\logger\logger.vcxproj">
|
<ProjectReference Include="..\common\logger\logger.vcxproj">
|
||||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\common\notifications\notifications.vcxproj">
|
|
||||||
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\common\SettingsAPI\SetttingsAPI.vcxproj">
|
<ProjectReference Include="..\common\SettingsAPI\SetttingsAPI.vcxproj">
|
||||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\common\updating\updating.vcxproj">
|
|
||||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="resource.h" />
|
<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::wstring runnerLogPath = L"RunnerLogs\\runner-log.txt";
|
||||||
inline const static std::string actionRunnerLoggerName = "action-runner";
|
inline const static std::string actionRunnerLoggerName = "action-runner";
|
||||||
inline const static std::wstring actionRunnerLogPath = L"RunnerLogs\\action-runner-log.txt";
|
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::string launcherLoggerName = "launcher";
|
||||||
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
|
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
|
||||||
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.txt";
|
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.txt";
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include "notifications.h"
|
#include "notifications.h"
|
||||||
#include "utils/com_object_factory.h"
|
#include "utils/com_object_factory.h"
|
||||||
#include "utils/window.h"
|
#include "utils/window.h"
|
||||||
#include "winstore/winstore.h"
|
|
||||||
|
|
||||||
#include <unknwn.h>
|
#include <unknwn.h>
|
||||||
#include <winrt/base.h>
|
#include <winrt/base.h>
|
||||||
@ -201,41 +200,6 @@ void notifications::override_application_id(const std::wstring_view appID)
|
|||||||
SetCurrentProcessExplicitAppUserModelID(APPLICATION_ID.c_str());
|
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)
|
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
|
// The toast won't be actually activated in the background, since it doesn't have any buttons
|
||||||
@ -402,7 +366,7 @@ void notifications::show_toast_with_activations(std::wstring message,
|
|||||||
NotificationData data{ map };
|
NotificationData data{ map };
|
||||||
notification.Data(std::move(data));
|
notification.Data(std::move(data));
|
||||||
|
|
||||||
const auto notifier = winstore::running_as_packaged() ? ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
const auto notifier =
|
||||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||||
|
|
||||||
// Set a tag-related params if it has a valid length
|
// Set a tag-related params if it has a valid length
|
||||||
@ -431,8 +395,7 @@ void notifications::show_toast_with_activations(std::wstring message,
|
|||||||
|
|
||||||
void notifications::update_toast_progress_bar(std::wstring_view tag, progress_bar_params params)
|
void notifications::update_toast_progress_bar(std::wstring_view tag, progress_bar_params params)
|
||||||
{
|
{
|
||||||
const auto notifier = winstore::running_as_packaged() ?
|
const auto notifier =
|
||||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
|
||||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||||
|
|
||||||
float progress = std::clamp(params.progress, 0.0f, 1.0f);
|
float progress = std::clamp(params.progress, 0.0f, 1.0f);
|
||||||
@ -468,8 +431,7 @@ void notifications::remove_toasts_by_tag(std::wstring_view tag)
|
|||||||
|
|
||||||
void notifications::remove_all_scheduled_toasts()
|
void notifications::remove_all_scheduled_toasts()
|
||||||
{
|
{
|
||||||
const auto notifier = winstore::running_as_packaged() ? ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
const auto notifier = ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,6 @@ namespace notifications
|
|||||||
constexpr inline const wchar_t UPDATING_PROCESS_TOAST_TAG[] = L"PTUpdateNotifyTag";
|
constexpr inline const wchar_t UPDATING_PROCESS_TOAST_TAG[] = L"PTUpdateNotifyTag";
|
||||||
|
|
||||||
void override_application_id(const std::wstring_view appID);
|
void override_application_id(const std::wstring_view appID);
|
||||||
void register_background_toast_handler();
|
|
||||||
void run_desktop_app_activator_loop();
|
void run_desktop_app_activator_loop();
|
||||||
|
|
||||||
bool register_application_id(const std::wstring_view appName, const std::wstring_view iconPath);
|
bool register_application_id(const std::wstring_view appName, const std::wstring_view iconPath);
|
||||||
|
@ -39,11 +39,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\WinStore\Winstore.vcxproj">
|
|
||||||
<Project>{c502a854-53ac-4ebb-8dc0-e4af2191e4f6}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<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')" />
|
<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 "installer.h"
|
||||||
#include <common/version/version.h>
|
#include <common/version/version.h>
|
||||||
#include <common/notifications/notifications.h>
|
#include <common/utils/MsiUtils.h>
|
||||||
#include <common/utils/os-detect.h>
|
#include <common/utils/os-detect.h>
|
||||||
#include "utils/winapi_error.h"
|
#include "utils/winapi_error.h"
|
||||||
|
|
||||||
namespace // Strings in this namespace should not be localized
|
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 DONT_SHOW_AGAIN_RECORD_REGISTRY_PATH[] = L"delete_previous_powertoys_confirm";
|
||||||
|
|
||||||
const wchar_t TOAST_TITLE[] = L"PowerToys";
|
const wchar_t TOAST_TITLE[] = L"PowerToys";
|
||||||
|
|
||||||
const wchar_t MSIX_PACKAGE_NAME[] = L"Microsoft.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 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
|
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()
|
std::future<bool> uninstall_previous_msix_version_async()
|
||||||
{
|
{
|
||||||
winrt::Windows::Management::Deployment::PackageManager package_manager;
|
winrt::Windows::Management::Deployment::PackageManager package_manager;
|
||||||
@ -192,9 +43,4 @@ namespace updating
|
|||||||
}
|
}
|
||||||
co_return false;
|
co_return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_1809_or_older()
|
|
||||||
{
|
|
||||||
return !Is19H1OrHigher();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -4,18 +4,9 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
#include "notifications.h"
|
|
||||||
#include <common/version/helper.h>
|
#include <common/version/helper.h>
|
||||||
|
|
||||||
namespace updating
|
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();
|
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 "pch.h"
|
||||||
|
|
||||||
|
#include <common/utils/HttpClient.h>
|
||||||
#include <common/version/version.h>
|
#include <common/version/version.h>
|
||||||
#include <common/version/helper.h>
|
#include <common/version/helper.h>
|
||||||
|
|
||||||
#include "http_client.h"
|
|
||||||
#include "notifications.h"
|
|
||||||
#include "updating.h"
|
#include "updating.h"
|
||||||
|
|
||||||
#include <common/notifications/notifications.h>
|
|
||||||
#include <common/SettingsAPI/settings_helpers.h>
|
#include <common/SettingsAPI/settings_helpers.h>
|
||||||
#include <common/utils/json.h>
|
#include <common/utils/json.h>
|
||||||
|
|
||||||
@ -76,7 +74,7 @@ namespace updating
|
|||||||
throw std::runtime_error("Release object doesn't have the required asset");
|
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 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)
|
if (VERSION_MAJOR == 0 && VERSION_MINOR == 0)
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <winrt/Windows.Foundation.h>
|
#include <winrt/Windows.Foundation.h>
|
||||||
#include <expected.hpp>
|
#include <expected.hpp>
|
||||||
|
|
||||||
#include "notifications.h"
|
|
||||||
#include <common/version/helper.h>
|
#include <common/version/helper.h>
|
||||||
|
|
||||||
namespace updating
|
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::future<std::optional<std::filesystem::path>> download_new_version(const new_version_download_info& new_version);
|
||||||
std::filesystem::path get_pending_updates_path();
|
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
|
// non-localized
|
||||||
constexpr inline std::wstring_view INSTALLER_FILENAME_PATTERN = L"powertoyssetup";
|
constexpr inline std::wstring_view INSTALLER_FILENAME_PATTERN = L"powertoyssetup";
|
||||||
|
@ -35,20 +35,13 @@
|
|||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="dotnet_installation.h" />
|
|
||||||
<ClInclude Include="http_client.h" />
|
|
||||||
<ClInclude Include="installer.h" />
|
<ClInclude Include="installer.h" />
|
||||||
<ClInclude Include="notifications.h" />
|
|
||||||
<ClInclude Include="updating.h" />
|
<ClInclude Include="updating.h" />
|
||||||
<ClInclude Include="updateState.h" />
|
<ClInclude Include="updateState.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="winstore.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="dotnet_installation.cpp" />
|
|
||||||
<ClCompile Include="http_client.cpp" />
|
|
||||||
<ClCompile Include="installer.cpp" />
|
<ClCompile Include="installer.cpp" />
|
||||||
<ClCompile Include="notifications.cpp" />
|
|
||||||
<ClCompile Include="updating.cpp" />
|
<ClCompile Include="updating.cpp" />
|
||||||
<ClCompile Include="updateState.cpp" />
|
<ClCompile Include="updateState.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
@ -56,9 +49,6 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\notifications\notifications.vcxproj">
|
|
||||||
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\SettingsAPI\SetttingsAPI.vcxproj">
|
<ProjectReference Include="..\SettingsAPI\SetttingsAPI.vcxproj">
|
||||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
@ -21,21 +21,15 @@
|
|||||||
<ClInclude Include="updating.h">
|
<ClInclude Include="updating.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</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">
|
<ClInclude Include="installer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="winstore.h">
|
<ClInclude Include="winstore.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="updateState.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
@ -44,18 +38,12 @@
|
|||||||
<ClCompile Include="updating.cpp">
|
<ClCompile Include="updating.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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">
|
<ClCompile Include="installer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="updateState.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<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 <shellapi.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
|
||||||
|
#include <winrt/base.h>
|
||||||
|
#include <winrt/Windows.Foundation.Collections.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
#include <common/utils/winapi_error.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">
|
<data name="GITHUB_NEW_VERSION_UPDATE_NOW" xml:space="preserve">
|
||||||
<value>Update now</value>
|
<value>Update now</value>
|
||||||
</data>
|
</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">
|
<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>
|
<value>An update to PowerToys is available. Visit our GitHub page to update.</value>
|
||||||
</data>
|
</data>
|
||||||
@ -109,12 +106,6 @@
|
|||||||
<data name="TOAST_TITLE" xml:space="preserve">
|
<data name="TOAST_TITLE" xml:space="preserve">
|
||||||
<value>PowerToys Update</value>
|
<value>PowerToys Update</value>
|
||||||
</data>
|
</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">
|
<data name="SETTINGS_MENU_TEXT" xml:space="preserve">
|
||||||
<value>Settings</value>
|
<value>Settings</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -2,60 +2,98 @@
|
|||||||
|
|
||||||
#include "Generated Files/resource.h"
|
#include "Generated Files/resource.h"
|
||||||
|
|
||||||
#include "action_runner_utils.h"
|
#include "ActionRunnerUtils.h"
|
||||||
#include "general_settings.h"
|
#include "general_settings.h"
|
||||||
#include "update_utils.h"
|
#include "UpdateUtils.h"
|
||||||
|
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
|
#include <common/notifications/notifications.h>
|
||||||
#include <common/updating/installer.h>
|
#include <common/updating/installer.h>
|
||||||
#include <common/updating/http_client.h>
|
|
||||||
#include <common/updating/updating.h>
|
#include <common/updating/updating.h>
|
||||||
#include <common/updating/updateState.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/resources.h>
|
||||||
#include <common/utils/timeutil.h>
|
#include <common/utils/timeutil.h>
|
||||||
|
#include <common/version/version.h>
|
||||||
auto Strings = create_notifications_strings();
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr int64_t UPDATE_CHECK_INTERVAL_MINUTES = 60 * 24;
|
constexpr int64_t UPDATE_CHECK_INTERVAL_MINUTES = 60 * 24;
|
||||||
constexpr int64_t UPDATE_CHECK_AFTER_FAILED_INTERVAL_MINUTES = 60 * 2;
|
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())
|
void ShowNewVersionAvailable(const new_version_download_info& info)
|
||||||
{
|
{
|
||||||
// No MSI version detected
|
remove_toasts_by_tag(UPDATING_PROCESS_TOAST_TAG);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!updating::offer_msi_uninstallation(Strings))
|
toast_params toast_params{ UPDATING_PROCESS_TOAST_TAG, false };
|
||||||
{
|
std::wstring contents = GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_AVAILABLE);
|
||||||
// User declined to uninstall or opted for "Don't show again"
|
contents += L'\n';
|
||||||
return false;
|
contents += CurrentVersionToNextVersion(info);
|
||||||
}
|
|
||||||
auto sei = launch_action_runner(L"-uninstall_msi");
|
|
||||||
|
|
||||||
WaitForSingleObject(sei.hProcess, INFINITE);
|
show_toast_with_activations(std::move(contents),
|
||||||
DWORD exit_code = 0;
|
GET_RESOURCE_STRING(IDS_TOAST_TITLE),
|
||||||
GetExitCodeProcess(sei.hProcess, &exit_code);
|
{},
|
||||||
CloseHandle(sei.hProcess);
|
{ link_button{ GET_RESOURCE_STRING(IDS_GITHUB_NEW_VERSION_UPDATE_NOW),
|
||||||
return exit_code == 0;
|
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;
|
using namespace updating;
|
||||||
|
|
||||||
bool could_be_costly_connection()
|
bool IsMeteredConnection()
|
||||||
{
|
{
|
||||||
using namespace winrt::Windows::Networking::Connectivity;
|
using namespace winrt::Windows::Networking::Connectivity;
|
||||||
ConnectionProfile internetConnectionProfile = NetworkInformation::GetInternetConnectionProfile();
|
ConnectionProfile internetConnectionProfile = NetworkInformation::GetInternetConnectionProfile();
|
||||||
return internetConnectionProfile && internetConnectionProfile.IsWwanConnectionProfile();
|
return internetConnectionProfile && internetConnectionProfile.IsWwanConnectionProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_new_version_info(const github_version_info& version_info,
|
void ProcessNewVersionInfo(const github_version_info& version_info,
|
||||||
UpdateState& state,
|
UpdateState& state,
|
||||||
const bool download_update,
|
const bool download_update,
|
||||||
const bool show_notifications)
|
const bool show_notifications)
|
||||||
@ -89,7 +127,7 @@ void process_new_version_info(const github_version_info& version_info,
|
|||||||
state.downloadedInstallerFilename = new_version_info.installer_filename;
|
state.downloadedInstallerFilename = new_version_info.installer_filename;
|
||||||
if (show_notifications)
|
if (show_notifications)
|
||||||
{
|
{
|
||||||
notifications::show_new_version_available(new_version_info, Strings);
|
ShowNewVersionAvailable(new_version_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -106,12 +144,12 @@ void process_new_version_info(const github_version_info& version_info,
|
|||||||
state.downloadedInstallerFilename = {};
|
state.downloadedInstallerFilename = {};
|
||||||
if (show_notifications)
|
if (show_notifications)
|
||||||
{
|
{
|
||||||
notifications::show_open_settings_for_update(Strings);
|
ShowOpenSettingsForUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void periodic_update_worker()
|
void PeriodicUpdateWorker()
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -129,15 +167,15 @@ void periodic_update_worker()
|
|||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::minutes{ sleep_minutes_till_next_update });
|
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;
|
bool version_info_obtained = false;
|
||||||
try
|
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())
|
if (new_version_info.has_value())
|
||||||
{
|
{
|
||||||
version_info_obtained = true;
|
version_info_obtained = true;
|
||||||
process_new_version_info(*new_version_info, state, download_update, true);
|
ProcessNewVersionInfo(*new_version_info, state, download_update, true);
|
||||||
}
|
}
|
||||||
else
|
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");
|
Logger::trace(L"Check for updates callback invoked");
|
||||||
auto state = UpdateState::read();
|
auto state = UpdateState::read();
|
||||||
try
|
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 (!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
|
// 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{};
|
new_version_info = version_up_to_date{};
|
||||||
Logger::error(L"Couldn't obtain version info from github: {}", new_version_info.error());
|
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;
|
const bool download_update = !IsMeteredConnection() && get_general_settings().downloadUpdatesAutomatically;
|
||||||
process_new_version_info(*new_version_info, state, download_update, false);
|
ProcessNewVersionInfo(*new_version_info, state, download_update, false);
|
||||||
UpdateState::store([&](UpdateState& v) {
|
UpdateState::store([&](UpdateState& v) {
|
||||||
v = std::move(state);
|
v = std::move(state);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (...)
|
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
|
#pragma once
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#include <common/updating/updating.h>
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
SHELLEXECUTEINFOW launch_action_runner(const wchar_t* cmdline);
|
void PeriodicUpdateWorker();
|
||||||
|
void CheckForUpdatesCallback();
|
||||||
|
|
||||||
namespace cmdArg
|
namespace cmdArg
|
||||||
{
|
{
|
||||||
@ -16,8 +16,7 @@ namespace cmdArg
|
|||||||
const inline wchar_t* UPDATE_STAGE2_RESTART_PT = L"restart";
|
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* 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";
|
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 <common/SettingsAPI/settings_helpers.h>
|
||||||
#include "powertoy_module.h"
|
#include "powertoy_module.h"
|
||||||
#include <common/themes/windows_colors.h>
|
#include <common/themes/windows_colors.h>
|
||||||
#include <common/winstore/winstore.h>
|
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include <common/utils/elevation.h>
|
#include <common/utils/elevation.h>
|
||||||
@ -22,7 +21,6 @@ json::JsonObject GeneralSettings::to_json()
|
|||||||
{
|
{
|
||||||
json::JsonObject result;
|
json::JsonObject result;
|
||||||
|
|
||||||
result.SetNamedValue(L"packaged", json::value(isPackaged));
|
|
||||||
result.SetNamedValue(L"startup", json::value(isStartupEnabled));
|
result.SetNamedValue(L"startup", json::value(isStartupEnabled));
|
||||||
if (!startupDisabledReason.empty())
|
if (!startupDisabledReason.empty())
|
||||||
{
|
{
|
||||||
@ -65,7 +63,6 @@ GeneralSettings get_general_settings()
|
|||||||
{
|
{
|
||||||
const bool is_user_admin = check_user_is_admin();
|
const bool is_user_admin = check_user_is_admin();
|
||||||
GeneralSettings settings{
|
GeneralSettings settings{
|
||||||
.isPackaged = winstore::running_as_packaged(),
|
|
||||||
.isElevated = is_process_elevated(),
|
.isElevated = is_process_elevated(),
|
||||||
.isRunElevated = run_as_elevated,
|
.isRunElevated = run_as_elevated,
|
||||||
.isAdmin = is_user_admin,
|
.isAdmin = is_user_admin,
|
||||||
@ -75,31 +72,7 @@ GeneralSettings get_general_settings()
|
|||||||
.powerToysVersion = get_product_version()
|
.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())
|
for (auto& [name, powertoy] : modules())
|
||||||
{
|
{
|
||||||
@ -118,12 +91,6 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
|
|||||||
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean))
|
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean))
|
||||||
{
|
{
|
||||||
const bool startup = general_configs.GetNamedBoolean(L"startup");
|
const bool startup = general_configs.GetNamedBoolean(L"startup");
|
||||||
if (winstore::running_as_packaged())
|
|
||||||
{
|
|
||||||
winstore::switch_startup_task_state_async(startup).wait();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (startup)
|
if (startup)
|
||||||
{
|
{
|
||||||
if (is_process_elevated())
|
if (is_process_elevated())
|
||||||
@ -152,7 +119,6 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
|
|||||||
delete_auto_start_task_for_this_user();
|
delete_auto_start_task_for_this_user();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (json::has(general_configs, L"enabled"))
|
if (json::has(general_configs, L"enabled"))
|
||||||
{
|
{
|
||||||
for (const auto& enabled_element : general_configs.GetNamedObject(L"enabled"))
|
for (const auto& enabled_element : general_configs.GetNamedObject(L"enabled"))
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
struct GeneralSettings
|
struct GeneralSettings
|
||||||
{
|
{
|
||||||
bool isPackaged;
|
|
||||||
bool isStartupEnabled;
|
bool isStartupEnabled;
|
||||||
std::wstring startupDisabledReason;
|
std::wstring startupDisabledReason;
|
||||||
std::map<std::wstring, bool> isModulesEnabledMap;
|
std::map<std::wstring, bool> isModulesEnabledMap;
|
||||||
|
@ -22,10 +22,9 @@
|
|||||||
#include <common/utils/elevation.h>
|
#include <common/utils/elevation.h>
|
||||||
#include <common/utils/processApi.h>
|
#include <common/utils/processApi.h>
|
||||||
#include <common/utils/resources.h>
|
#include <common/utils/resources.h>
|
||||||
#include <common/winstore/winstore.h>
|
|
||||||
|
|
||||||
#include "update_utils.h"
|
#include "UpdateUtils.h"
|
||||||
#include "action_runner_utils.h"
|
#include "ActionRunnerUtils.h"
|
||||||
|
|
||||||
#include <winrt/Windows.System.h>
|
#include <winrt/Windows.System.h>
|
||||||
|
|
||||||
@ -45,8 +44,6 @@
|
|||||||
#include <common/utils/window.h>
|
#include <common/utils/window.h>
|
||||||
#include <common/version/version.h>
|
#include <common/version/version.h>
|
||||||
|
|
||||||
extern updating::notifications::strings Strings;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const wchar_t PT_URI_PROTOCOL_SCHEME[] = L"powertoys://";
|
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();
|
debug_verify_launcher_assets();
|
||||||
|
|
||||||
std::thread{ [] {
|
std::thread{ [] {
|
||||||
periodic_update_worker();
|
PeriodicUpdateWorker();
|
||||||
} }.detach();
|
} }.detach();
|
||||||
|
|
||||||
if (winstore::running_as_packaged())
|
|
||||||
{
|
|
||||||
std::thread{ [] {
|
|
||||||
start_msi_uninstallation_sequence();
|
|
||||||
} }.detach();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::thread{ [] {
|
std::thread{ [] {
|
||||||
if (updating::uninstall_previous_msix_version_async().get())
|
if (updating::uninstall_previous_msix_version_async().get())
|
||||||
{
|
{
|
||||||
notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L"PowerToys");
|
notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L"PowerToys");
|
||||||
}
|
}
|
||||||
} }.detach();
|
} }.detach();
|
||||||
}
|
|
||||||
|
|
||||||
notifications::register_background_toast_handler();
|
|
||||||
|
|
||||||
chdir_current_executable();
|
chdir_current_executable();
|
||||||
// Load Powertoys DLLs
|
// Load Powertoys DLLs
|
||||||
@ -258,7 +244,7 @@ toast_notification_handler_result toast_notification_handler(const std::wstring_
|
|||||||
else if (param.starts_with(update_now))
|
else if (param.starts_with(update_now))
|
||||||
{
|
{
|
||||||
std::wstring args{ cmdArg::UPDATE_NOW_LAUNCH_STAGE1 };
|
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;
|
return toast_notification_handler_result::exit_success;
|
||||||
}
|
}
|
||||||
else if (param == couldnt_toggle_powerpreview_modules_disable)
|
else if (param == couldnt_toggle_powerpreview_modules_disable)
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\common\interop\two_way_pipe_message_ipc.cpp" />
|
<ClCompile Include="..\common\interop\two_way_pipe_message_ipc.cpp" />
|
||||||
<ClCompile Include="action_runner_utils.cpp" />
|
|
||||||
<ClCompile Include="auto_start_helper.cpp" />
|
<ClCompile Include="auto_start_helper.cpp" />
|
||||||
<ClCompile Include="CentralizedHotkeys.cpp" />
|
<ClCompile Include="CentralizedHotkeys.cpp" />
|
||||||
<ClCompile Include="general_settings.cpp" />
|
<ClCompile Include="general_settings.cpp" />
|
||||||
@ -62,17 +61,17 @@
|
|||||||
<ClCompile Include="trace.cpp" />
|
<ClCompile Include="trace.cpp" />
|
||||||
<ClCompile Include="tray_icon.cpp" />
|
<ClCompile Include="tray_icon.cpp" />
|
||||||
<ClCompile Include="unhandled_exception_handler.cpp" />
|
<ClCompile Include="unhandled_exception_handler.cpp" />
|
||||||
<ClCompile Include="update_utils.cpp" />
|
<ClCompile Include="UpdateUtils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="action_runner_utils.h" />
|
<ClInclude Include="ActionRunnerUtils.h" />
|
||||||
<ClInclude Include="auto_start_helper.h" />
|
<ClInclude Include="auto_start_helper.h" />
|
||||||
<ClInclude Include="CentralizedHotkeys.h" />
|
<ClInclude Include="CentralizedHotkeys.h" />
|
||||||
<ClInclude Include="general_settings.h" />
|
<ClInclude Include="general_settings.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="centralized_kb_hook.h" />
|
<ClInclude Include="centralized_kb_hook.h" />
|
||||||
<ClInclude Include="settings_telemetry.h" />
|
<ClInclude Include="settings_telemetry.h" />
|
||||||
<ClInclude Include="update_utils.h" />
|
<ClInclude Include="UpdateUtils.h" />
|
||||||
<ClInclude Include="powertoy_module.h" />
|
<ClInclude Include="powertoy_module.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="restart_elevated.h" />
|
<ClInclude Include="restart_elevated.h" />
|
||||||
@ -111,9 +110,6 @@
|
|||||||
<ProjectReference Include="..\common\updating\updating.vcxproj">
|
<ProjectReference Include="..\common\updating\updating.vcxproj">
|
||||||
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
<Project>{17da04df-e393-4397-9cf0-84dabe11032e}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\common\WinStore\Winstore.vcxproj">
|
|
||||||
<Project>{c502a854-53ac-4ebb-8dc0-e4af2191e4f6}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
@ -27,10 +27,7 @@
|
|||||||
<ClCompile Include="restart_elevated.cpp">
|
<ClCompile Include="restart_elevated.cpp">
|
||||||
<Filter>Utils</Filter>
|
<Filter>Utils</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="update_utils.cpp">
|
<ClCompile Include="UpdateUtils.cpp">
|
||||||
<Filter>Utils</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="action_runner_utils.cpp">
|
|
||||||
<Filter>Utils</Filter>
|
<Filter>Utils</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="centralized_kb_hook.cpp">
|
<ClCompile Include="centralized_kb_hook.cpp">
|
||||||
@ -72,10 +69,10 @@
|
|||||||
<ClInclude Include="restart_elevated.h">
|
<ClInclude Include="restart_elevated.h">
|
||||||
<Filter>Utils</Filter>
|
<Filter>Utils</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="update_utils.h">
|
<ClInclude Include="UpdateUtils.h">
|
||||||
<Filter>Utils</Filter>
|
<Filter>Utils</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="action_runner_utils.h">
|
<ClInclude Include="ActionRunnerUtils.h">
|
||||||
<Filter>Utils</Filter>
|
<Filter>Utils</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="resource.h">
|
<ClInclude Include="resource.h">
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "tray_icon.h"
|
#include "tray_icon.h"
|
||||||
#include "general_settings.h"
|
#include "general_settings.h"
|
||||||
#include "restart_elevated.h"
|
#include "restart_elevated.h"
|
||||||
#include "update_utils.h"
|
#include "UpdateUtils.h"
|
||||||
#include "centralized_kb_hook.h"
|
#include "centralized_kb_hook.h"
|
||||||
|
|
||||||
#include <common/utils/json.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")
|
else if (action == L"check_for_updates")
|
||||||
{
|
{
|
||||||
check_for_updates_settings_callback();
|
CheckForUpdatesCallback();
|
||||||
}
|
}
|
||||||
else if (action == L"request_update_state_date")
|
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
|
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.
|
// Gets or sets a value indicating whether run powertoys on start-up.
|
||||||
[JsonPropertyName("startup")]
|
[JsonPropertyName("startup")]
|
||||||
public bool Startup { get; set; }
|
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.")]
|
[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()
|
public GeneralSettings()
|
||||||
{
|
{
|
||||||
Packaged = false;
|
|
||||||
Startup = false;
|
Startup = false;
|
||||||
IsAdmin = false;
|
IsAdmin = false;
|
||||||
IsElevated = false;
|
IsElevated = false;
|
||||||
|
@ -112,7 +112,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _packaged;
|
|
||||||
private bool _startup;
|
private bool _startup;
|
||||||
private bool _isElevated;
|
private bool _isElevated;
|
||||||
private bool _runElevated;
|
private bool _runElevated;
|
||||||
@ -130,24 +129,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||||||
private bool _isNewVersionDownloading;
|
private bool _isNewVersionDownloading;
|
||||||
private bool _isNewVersionChecked;
|
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.
|
// Gets or sets a value indicating whether run powertoys on start-up.
|
||||||
public bool Startup
|
public bool Startup
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,6 @@ namespace ViewModelTests
|
|||||||
|
|
||||||
// Verify that the old settings persisted
|
// Verify that the old settings persisted
|
||||||
Assert.AreEqual(originalGeneralSettings.AutoDownloadUpdates, viewModel.AutoDownloadUpdates);
|
Assert.AreEqual(originalGeneralSettings.AutoDownloadUpdates, viewModel.AutoDownloadUpdates);
|
||||||
Assert.AreEqual(originalGeneralSettings.Packaged, viewModel.Packaged);
|
|
||||||
Assert.AreEqual(originalGeneralSettings.PowertoysVersion, viewModel.PowerToysVersion);
|
Assert.AreEqual(originalGeneralSettings.PowertoysVersion, viewModel.PowerToysVersion);
|
||||||
Assert.AreEqual(originalGeneralSettings.RunElevated, viewModel.RunElevated);
|
Assert.AreEqual(originalGeneralSettings.RunElevated, viewModel.RunElevated);
|
||||||
Assert.AreEqual(originalGeneralSettings.Startup, viewModel.Startup);
|
Assert.AreEqual(originalGeneralSettings.Startup, viewModel.Startup);
|
||||||
|
Loading…
Reference in New Issue
Block a user