diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index 5e4b123dfe..88d2e99e5a 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -122,12 +122,16 @@ AWAYMODE
AYUV
backend
backtracer
+BAEC
+BAF
bak
bbwe
bck
Bcl
+BEEE
betadele
betsegaw
+BFB
BGR
bgra
BGSOUNDS
@@ -157,6 +161,7 @@ boolalpha
Bools
Boostrapper
bootstrapper
+BOOTSTRAPPERINSTALLFOLDER
Bopomofo
BOTTOMALIGN
BPBF
@@ -175,6 +180,7 @@ buf
BUFSIZE
bugreport
Buid
+BUILDARCH
buildtransitive
BValue
bytearray
@@ -195,6 +201,7 @@ CDeclaration
CDEF
cdpx
CENTERALIGN
+CFDB
cguid
changecursor
Changemove
@@ -352,6 +359,8 @@ Datavalue
DATAW
davidegiacometti
Dayof
+DBCD
+DBDA
dbg
Dbghelp
DBLCLKS
@@ -367,6 +376,7 @@ declspec
decltype
Dedup
deduplicate
+DEFAULTBOOTSTRAPPERINSTALLFOLDER
DEFAULTCOLOR
DEFAULTFLAGS
DEFAULTONLY
@@ -477,6 +487,9 @@ dwrite
dxgi
dxgiformat
dxguid
+EAF
+EBA
+EBE
ecount
ededf
EDITKEYBOARD
@@ -484,6 +497,8 @@ editkeyboardwindow
editorconfig
EDITSHORTCUTS
editshortcutswindow
+EFBD
+efgh
EFile
egistry
ekus
@@ -551,7 +566,10 @@ FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
Farbraum
FARPROC
+FBF
+FCCD
fdw
+FEEBD
feimage
ffaa
fff
@@ -850,6 +868,8 @@ INPUTTYPE
INSTALLDESKTOPSHORTCUT
INSTALLDIR
INSTALLFOLDER
+INSTALLFOLDERTOBOOTSTRAPPERINSTALLFOLDER
+INSTALLFOLDERTOPREVIOUSINSTALLFOLDER
INSTALLLOCATION
INSTALLLOGATTRIBUTES
INSTALLLOGMODE
@@ -1365,6 +1385,7 @@ outro
outsettings
OVERLAPPEDWINDOW
overlaywindow
+Overridable
OWNDC
PACL
PAINTSTRUCT
@@ -1463,6 +1484,7 @@ previewer
PREVIEWHANDLERFRAMEINFO
previewpane
previouscamera
+PREVIOUSINSTALLFOLDER
PREVIOUSVERSIONSINSTALLED
prevpane
prgms
@@ -2100,6 +2122,7 @@ wcsncmp
wcsnicmp
wdp
wdupenv
+We'd
weakme
webcam
webpage
diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json
index 6a2fdfee12..85705551a6 100644
--- a/.pipelines/ESRPSigning_core.json
+++ b/.pipelines/ESRPSigning_core.json
@@ -4,7 +4,7 @@
"SignBatches": [
{
"MatchedPath": [
- "!(ModernWpf)*.resources.dll",
+ "*.resources.dll",
"PowerToysSetupCustomActions.dll",
diff --git a/.pipelines/build-installer-MSI.cmd b/.pipelines/build-installer-MSI.cmd
new file mode 100644
index 0000000000..0070994cec
--- /dev/null
+++ b/.pipelines/build-installer-MSI.cmd
@@ -0,0 +1,5 @@
+cd /D "%~dp0"
+
+call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
+SET IsPipeline=1
+call msbuild ../installer/PowerToysSetup.sln /target:PowerToysInstaller /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1
diff --git a/.pipelines/ci/templates/build-powertoys-steps.yml b/.pipelines/ci/templates/build-powertoys-steps.yml
index 68e15e09a0..d32cb5961f 100644
--- a/.pipelines/ci/templates/build-powertoys-steps.yml
+++ b/.pipelines/ci/templates/build-powertoys-steps.yml
@@ -93,25 +93,6 @@ steps:
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
-- task: NuGetCommand@2
- displayName: Restore NuGet packages for PowerToysBootstrapper.sln
- inputs:
- command: restore
- feedsToUse: config
- configPath: NuGet.config
- restoreSolution: installer\PowerToysBootstrapper\PowerToysBootstrapper.sln
- restoreDirectory: '$(Build.SourcesDirectory)\installer\PowerToysBootstrapper\packages'
-
-- task: VSBuild@1
- displayName: 'Build PowerToysBootstrapper.sln'
- inputs:
- solution: '**\installer\PowerToysBootstrapper\PowerToysBootstrapper.sln'
- vsVersion: 16.0
- platform: '$(BuildPlatform)'
- configuration: '$(BuildConfiguration)'
- msbuildArgs: ${{ parameters.additionalBuildArguments }}
- maximumCpuCount: true
-
# directly not doing WinAppDriver testing
- task: VSTest@2
displayName: 'MS Tests'
diff --git a/.pipelines/release.yml b/.pipelines/release.yml
index e90f57d89a..878d26773e 100644
--- a/.pipelines/release.yml
+++ b/.pipelines/release.yml
@@ -211,7 +211,7 @@ jobs:
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
- msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
+ msbuildArgs: /p:CIBuild=true /target:PowerToysInstaller /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
@@ -231,7 +231,7 @@ jobs:
- task: VSBuild@1
displayName: Build Bootstrapper
inputs:
- solution: '**/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln'
+ solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
@@ -239,11 +239,53 @@ jobs:
clean: true
maximumCpuCount: true
+ - task: CmdLine@2
+ displayName: 'Insignia: Extract Engine from Bundle'
+ inputs:
+ script: '.\installer\packages\WiX.3.11.2\tools\insignia.exe -ib installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe -o installer\engine.exe'
+
+
+ - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
+ displayName: 'ESRP CodeSigning (Engine)'
+ inputs:
+ ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
+ FolderPath: 'installer'
+ Pattern: engine.exe
+ signConfigType: inlineSignParams
+ inlineOperation: |
+ [
+ {
+ "KeyCode": "CP-230012",
+ "OperationCode": "SigntoolSign",
+ "Parameters": {
+ "OpusName": "Microsoft",
+ "OpusInfo": "http://www.microsoft.com",
+ "FileDigest": "/fd \"SHA256\"",
+ "PageHash": "/NPH",
+ "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
+ },
+ "ToolName": "sign",
+ "ToolVersion": "1.0"
+ },
+ {
+ "KeyCode": "CP-230012",
+ "OperationCode": "SigntoolVerify",
+ "Parameters": {},
+ "ToolName": "sign",
+ "ToolVersion": "1.0"
+ }
+ ]
+
+ - task: CmdLine@2
+ displayName: 'Insignia: Merge Engine into Bundle'
+ inputs:
+ script: '.\installer\packages\WiX.3.11.2\tools\insignia.exe -ab installer\engine.exe installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe -o installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe'
+
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign Boostrapper
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
- FolderPath: 'installer/PowerToysBootstrapper/$(BuildPlatform)\$(BuildConfiguration)'
+ FolderPath: 'installer/PowerToysSetup/$(BuildPlatform)\$(BuildConfiguration)'
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
diff --git a/doc/devdocs/logging.md b/doc/devdocs/logging.md
index ba3a50dd2c..57f2d13844 100644
--- a/doc/devdocs/logging.md
+++ b/doc/devdocs/logging.md
@@ -6,4 +6,4 @@ We use the awesome [spdlog](https://github.com/gabime/spdlog) library for loggin
```
It'll add the required include dirs and link the library binary itself.
-You can see many example usage of the library in its repository or in the [bootstrapper project](../../installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp).
+
diff --git a/doc/devdocs/readme.md b/doc/devdocs/readme.md
index b5425a0233..8dd646b192 100644
--- a/doc/devdocs/readme.md
+++ b/doc/devdocs/readme.md
@@ -66,7 +66,6 @@ The installer can only be compiled in `Release` mode, step 1 and 2 must be done
2. Compile `BugReportTool.sln` tool. Path from root: `tools\BugReportTool\BugReportTool.sln` (details listed below)
3. Compile `WebcamReportTool.sln` tool. Path from root: `tools\WebcamReportTool\WebcamReportTool.sln` (details listed below)
4. Compile `PowerToysSetup.sln` Path from root: `installer\PowerToysSetup.sln` (details listed below)
-5. Compile `PowerToysBootstrapper.sln` Path from root: `installer\PowerToysBootstrapper\PowerToysBootstrapper.sln` (details listed below)
### Prerequisites for building the MSI installer
@@ -85,7 +84,7 @@ The installer can only be compiled in `Release` mode, step 1 and 2 must be done
2. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
3. From the `Build` menu, choose `Build Solution`.
-### Locally compiling the .MSI installer
+### Locally compiling the installer
1. Open `installer\PowerToysSetup.sln`
2. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
@@ -93,14 +92,6 @@ The installer can only be compiled in `Release` mode, step 1 and 2 must be done
The resulting `PowerToysSetup.msi` installer will be available in the `installer\PowerToysSetup\x64\Release\` folder.
-### Locally compiling the .EXE Bootstrapper installer
-
-1. Open `installer\PowerToysBootstrapper\PowerToysBootstrapper.sln`
-2. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
-3. From the `Build` menu choose `Build Solution`.
-
-The `PowerToysSetup-0.0.1-x64.exe` binary is created in the `installer\PowerToysBootstrapper\x64\Release\` folder.
-
#### Supported arguments for the .EXE Bootstrapper installer
Head over to the wiki to see the [full list of supported installer arguments][installerArgWiki].
diff --git a/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln b/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln
deleted file mode 100644
index 8f25336454..0000000000
--- a/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln
+++ /dev/null
@@ -1,43 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30320.27
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bootstrapper", "bootstrapper\bootstrapper.vcxproj", "{D194E3AA-F824-4CA9-9A58-034DD6B7D022}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "..\..\src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Version", "..\..\src\common\version\version.vcxproj", "{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetttingsAPI", "..\..\src\common\SettingsAPI\SetttingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.ActiveCfg = Debug|x64
- {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.Build.0 = Debug|x64
- {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Release|x64.ActiveCfg = Release|x64
- {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Release|x64.Build.0 = Release|x64
- {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64
- {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.Build.0 = Debug|x64
- {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.ActiveCfg = Release|x64
- {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.Build.0 = Release|x64
- {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.ActiveCfg = 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.Build.0 = Release|x64
- {6955446D-23F7-4023-9BB3-8657F904AF99}.Debug|x64.ActiveCfg = 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.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {B288A538-1B79-4782-A737-14CD9CF07F58}
- EndGlobalSection
-EndGlobal
diff --git a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp b/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp
deleted file mode 100644
index c5f6383350..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "pch.h"
-
-#include "DotnetInstallation.h"
-
-#include
-#include
-#include
-namespace fs = std::filesystem;
-
-namespace updating
-{
- constexpr size_t REQUIRED_MINIMAL_PATCH = 20;
-
- bool dotnet_is_installed()
- {
- auto runtimes = exec_and_read_output(LR"(dotnet --list-runtimes)");
- if (!runtimes)
- {
- return false;
- }
- std::regex dotnet3_1_x{ R"(Microsoft\.WindowsDesktop\.App\s3\.1\.(\d+))" };
-
- size_t latestPatchInstalled = 0;
- using rexit = std::sregex_iterator;
- for (auto it = rexit{ begin(*runtimes), end(*runtimes), dotnet3_1_x }; it != rexit{}; ++it)
- {
- if (!it->ready() || it->size() < 2)
- {
- continue;
- }
- auto patchNumberGroup = (*it)[1];
- if (!patchNumberGroup.matched)
- {
- continue;
- }
- const auto patchString = patchNumberGroup.str();
- size_t patch = 0;
- if (auto [_, ec] = std::from_chars(&*begin(patchString), &*end(patchString), patch); ec == std::errc())
- {
- latestPatchInstalled = std::max(patch, latestPatchInstalled);
- }
- }
- return latestPatchInstalled >= REQUIRED_MINIMAL_PATCH;
- }
-
- std::optional download_dotnet()
- {
- const wchar_t DOTNET_DESKTOP_DOWNLOAD_LINK[] = L"https://download.visualstudio.microsoft.com/download/pr/93c69a29-d379-4a5d-bb9e-3116cc14de41/907bbc52446d8bb7baa0c6faebde1d44/windowsdesktop-runtime-3.1.20-win-x64.exe";
- const wchar_t DOTNET_DESKTOP_FILENAME[] = L"windowsdesktop-runtime.exe";
-
- auto dotnet_download_path = fs::temp_directory_path() / DOTNET_DESKTOP_FILENAME;
- winrt::Windows::Foundation::Uri download_link{ DOTNET_DESKTOP_DOWNLOAD_LINK };
-
- const size_t max_attempts = 3;
- bool download_success = false;
- for (size_t i = 0; i < max_attempts; ++i)
- {
- try
- {
- http::HttpClient client;
- client.download(download_link, dotnet_download_path).wait();
- download_success = true;
- break;
- }
- catch (...)
- {
- // couldn't download
- }
- }
- return download_success ? std::make_optional(dotnet_download_path) : std::nullopt;
- }
-
- bool install_dotnet(fs::path dotnet_download_path, const bool silent = false)
- {
- SHELLEXECUTEINFOW sei{ sizeof(sei) };
- sei.fMask = { SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE };
- sei.lpFile = dotnet_download_path.c_str();
- sei.nShow = SW_SHOWNORMAL;
- std::wstring dotnet_flags = L"/install ";
- dotnet_flags += silent ? L"/quiet" : L"/passive";
- sei.lpParameters = dotnet_flags.c_str();
- if (ShellExecuteExW(&sei) != TRUE)
- {
- return false;
- }
- WaitForSingleObject(sei.hProcess, INFINITE);
- CloseHandle(sei.hProcess);
- return true;
- }
-}
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h b/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h
deleted file mode 100644
index 67ff6ad3b9..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include
-#include
-
-namespace fs = std::filesystem;
-namespace updating
-{
- bool dotnet_is_installed();
- std::optional download_dotnet();
- bool install_dotnet(fs::path dotnet_download_path, const bool silent);
-}
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/Resources.resx b/installer/PowerToysBootstrapper/bootstrapper/Resources.resx
deleted file mode 100644
index 85368cc467..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/Resources.resx
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- PowerToys Installer
-
-
- Couldn't download .NET Core Desktop Runtime 3.1, please install it manually.
-
-
- PowerToys installation error
-
-
- An update to PowerToys is available. Visit our GitHub page to update.
-
-
- Couldn't extract MSI installer.
-
-
- Extracting PowerToys MSI...
-
-
- Couldn't uninstall previous PowerToys version.
-
-
- Downloading .NET Core...
-
-
- Couldn't install .NET Core.
-
-
- Couldn't install new PowerToys version.
-
-
- A newer version is already installed.
-
-
- PowerToys requires Windows 10 version 1903 (May 2019 Update) or newer to run.
-
-
diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.base.rc b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.base.rc
deleted file mode 100644
index e28ff90e74..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.base.rc
+++ /dev/null
@@ -1,41 +0,0 @@
-#include
-#include "resource.h"
-#include "../../../src/common/version/version.h"
-
-MAINICON ICON "../../../src/runner/svgs/icon.ico"
-IDR_BIN_ICON BIN "../../../src/runner/svgs/icon.ico"
-
-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
-
-#include "Generated Files\installer_resource.rc"
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp
deleted file mode 100644
index eace67434e..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-#include "pch.h"
-#include "Generated Files/resource.h"
-
-#include "RcResource.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "DotnetInstallation.h"
-#include "progressbar_window.h"
-
-static bool g_Silent = false;
-
-#define STR_HELPER(x) #x
-#define STR(x) STR_HELPER(x)
-
-namespace // Strings in this namespace should not be localized
-{
- const wchar_t APPLICATION_ID[] = L"PowerToysInstaller";
- const char EXE_LOG_FILENAME[] = "powertoys-bootstrapper-exe-" STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_REVISION) ".log";
- const char MSI_LOG_FILENAME[] = "powertoys-bootstrapper-msi-" STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_REVISION) ".log";
-}
-
-#undef STR
-#undef STR_HELPER
-
-namespace fs = std::filesystem;
-
-std::optional ExtractEmbeddedInstaller(const fs::path extractPath)
-{
- auto executableRes = RcResource::create(IDR_BIN_MSIINSTALLER, L"BIN");
- if (!executableRes)
- {
- return std::nullopt;
- }
-
- std::wstring msiName(L"PowerToysSetup-" STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR) "." STRINGIZE(VERSION_REVISION) L"-");
- msiName += get_architecture_string(get_current_architecture()) + std::wstring(L".msi");
- auto installerPath = extractPath / msiName;
- return executableRes->saveAsFile(installerPath) ? std::make_optional(std::move(installerPath)) : std::nullopt;
-}
-
-void SetupLogger(fs::path directory, const spdlog::level::level_enum severity)
-{
- std::shared_ptr logger;
- auto nullLogger = spdlog::null_logger_mt("null");
- try
- {
- if (severity != spdlog::level::off)
- {
- logger = spdlog::basic_logger_mt("file", (directory / EXE_LOG_FILENAME).wstring());
-
- std::error_code _;
- const DWORD msiSev = severity == spdlog::level::debug ? INSTALLLOGMODE_VERBOSE : INSTALLLOGMODE_ERROR;
- const auto msiLogPath = directory / MSI_LOG_FILENAME;
- MsiEnableLogW(msiSev, msiLogPath.c_str(), INSTALLLOGATTRIBUTES_APPEND);
- }
- else
- {
- logger = nullLogger;
- }
-
- logger->set_pattern("[%L][%d-%m-%C-%T] %v");
- logger->set_level(severity);
- spdlog::set_default_logger(std::move(logger));
- spdlog::set_level(severity);
- spdlog::flush_every(std::chrono::seconds(5));
- }
- catch (...)
- {
- spdlog::set_default_logger(nullLogger);
- }
-}
-
-void CleanupSettingsFromOlderVersions()
-{
- try
- {
- const auto logSettingsFile = fs::path{ PTSettingsHelper::get_root_save_folder_location() } / PTSettingsHelper::log_settings_filename;
- if (fs::is_regular_file(logSettingsFile))
- {
- fs::remove(logSettingsFile);
- spdlog::info("Removed old log settings file");
- }
- else
- {
- spdlog::info("Old log settings file wasn't found");
- }
- }
- catch (...)
- {
- spdlog::error("Failed to cleanup old log settings");
- }
-}
-
-void ShowMessageBoxError(const wchar_t* message)
-{
- if (!g_Silent)
- {
- MessageBoxW(nullptr,
- message,
- GET_RESOURCE_STRING(IDS_BOOTSTRAPPER_PROGRESS_TITLE).c_str(),
- MB_OK | MB_ICONERROR);
- }
-}
-
-void ShowMessageBoxError(const UINT messageId)
-{
- ShowMessageBoxError(GET_RESOURCE_STRING(messageId).c_str());
-}
-
-bool uninstall_msi_version(const std::wstring& package_path)
-{
- const auto uninstall_result = MsiInstallProductW(package_path.c_str(), L"REMOVE=ALL");
- return ERROR_SUCCESS == uninstall_result;
-}
-
-struct InstalledVersionInfo
-{
- VersionHelper version;
- std::wstring install_folder;
-};
-std::optional get_installed_powertoys_version()
-{
- auto installed_path = GetMsiPackageInstalledPath();
- if (!installed_path)
- {
- return std::nullopt;
- }
- std::wstring executable_path = *installed_path + L"\\PowerToys.exe";
-
- // Get the version information for the file requested
- const DWORD fvSize = GetFileVersionInfoSizeW(executable_path.c_str(), nullptr);
- if (!fvSize)
- {
- return std::nullopt;
- }
-
- auto pbVersionInfo = std::make_unique(fvSize);
-
- if (!GetFileVersionInfoW(executable_path.c_str(), 0, fvSize, pbVersionInfo.get()))
- {
- return std::nullopt;
- }
-
- VS_FIXEDFILEINFO* fileInfo = nullptr;
- UINT fileInfoLen = 0;
- if (!VerQueryValueW(pbVersionInfo.get(), L"\\", reinterpret_cast(&fileInfo), &fileInfoLen))
- {
- return std::nullopt;
- }
- return InstalledVersionInfo{
- .version = VersionHelper{ (fileInfo->dwFileVersionMS >> 16) & 0xffff,
- (fileInfo->dwFileVersionMS >> 0) & 0xffff,
- (fileInfo->dwFileVersionLS >> 16) & 0xffff },
- .install_folder = std::move(*installed_path)
- };
-}
-
-void ReLaunchElevatedAndExit()
-{
- std::wstring params;
- int nCmdArgs = 0;
- LPWSTR* argList = CommandLineToArgvW(GetCommandLineW(), &nCmdArgs);
- for (int i = 1; i < nCmdArgs; ++i)
- {
- if (std::wstring_view{ argList[i] }.find(L' ') != std::wstring_view::npos)
- {
- params += L'"';
- params += argList[i];
- params += L'"';
- }
- else
- {
- params += argList[i];
- }
-
- if (i != nCmdArgs - 1)
- {
- params += L' ';
- }
- }
-
- const auto processHandle = run_elevated(argList[0], params.c_str());
- if (!processHandle)
- {
- spdlog::error("Couldn't restart elevated: ({})", GetLastError());
- return;
- }
-
- if (WaitForSingleObject(processHandle, 3600000) == WAIT_OBJECT_0)
- {
- DWORD exitCode = 0;
- GetExitCodeProcess(processHandle, &exitCode);
- std::exit(exitCode);
- }
- else
- {
- spdlog::error("Elevated setup process timed out after 60m: ({})", GetLastError());
- TerminateProcess(processHandle, 0);
- std::exit(1);
- }
-}
-
-int Bootstrapper(HINSTANCE hInstance)
-{
- winrt::init_apartment();
-
- fs::path logDir = PTSettingsHelper::get_root_save_folder_location();
-
- cxxopts::Options options{ "PowerToysBootstrapper" };
-
- // clang-format off
- options.add_options()
- ("h,help", "Show help")
- ("no_full_ui", "Use reduced UI for MSI")
- ("s,silent", "Suppress all UI, notifications and does not start PowerToys")
- ("no_start_pt", "Do not launch PowerToys after the installation is complete")
- ("start_pt", "Always launch PowerToys after the installation is complete")
- ("skip_dotnet_install", "Skip dotnet 3.X installation even if it's not detected")
- ("log_level", "Log level. Possible values: off|debug|error", cxxopts::value()->default_value("off"))
- ("log_dir", "Log directory", cxxopts::value()->default_value(logDir.string()))
- ("install_dir", "Installation directory", cxxopts::value()->default_value(""))
- ("extract_msi", "Extract MSI to the working directory and exit. Use only if you must access MSI directly.");
- // clang-format on
-
- cxxopts::ParseResult cmdArgs;
- bool showHelp = false;
- try
- {
- cmdArgs = options.parse(__argc, const_cast(__argv));
- }
- catch (...)
- {
- showHelp = true;
- }
-
- showHelp = showHelp || cmdArgs["help"].as();
- if (showHelp)
- {
- std::ostringstream helpMsg;
- helpMsg << options.help();
- MessageBoxA(nullptr, helpMsg.str().c_str(), "Help", MB_OK | MB_ICONINFORMATION);
- return 0;
- }
-
- g_Silent = cmdArgs["silent"].as();
- const bool noFullUI = cmdArgs["no_full_ui"].as();
- const bool skipDotnetInstall = cmdArgs["skip_dotnet_install"].as();
- const bool noStartPT = cmdArgs["no_start_pt"].as();
- const bool startPT = cmdArgs["start_pt"].as();
- const auto logLevel = cmdArgs["log_level"].as();
- const auto logDirArg = cmdArgs["log_dir"].as();
- const auto installDirArg = cmdArgs["install_dir"].as();
- const bool extractMsiOnly = cmdArgs["extract_msi"].as();
-
- std::wstring installFolderProp;
- if (!installDirArg.empty())
- {
- std::string installDir;
- if (installDirArg.find(' ') != std::string::npos)
- {
- installDir = "\"" + installDirArg + "\"";
- }
- else
- {
- installDir = installDirArg;
- }
-
- installFolderProp = std::wstring(installDir.length(), L' ');
- std::copy(installDir.begin(), installDir.end(), installFolderProp.begin());
- installFolderProp = L"INSTALLFOLDER=\"" + installFolderProp + L"\"";
- }
-
- try
- {
- fs::path logDirArgPath = logDirArg;
- if (fs::exists(logDirArgPath) && fs::is_directory(logDirArgPath))
- {
- logDir = logDirArgPath;
- }
- }
- catch (...)
- {
- }
-
- spdlog::level::level_enum severity = spdlog::level::debug;
- if (logLevel == "error")
- {
- severity = spdlog::level::err;
- }
-
- SetupLogger(logDir, severity);
- spdlog::debug("PowerToys Bootstrapper is launched\nnoFullUI: {}\nsilent: {}\nno_start_pt: {}\nskip_dotnet_install: {}\nlog_level: {}\ninstall_dir: {}\nextract_msi: {}\n", noFullUI, g_Silent, noStartPT, skipDotnetInstall, logLevel, installDirArg, extractMsiOnly);
-
- // If a user requested an MSI -> extract it and exit
- if (extractMsiOnly)
- {
- if (const auto installerPath = ExtractEmbeddedInstaller(fs::current_path()))
- {
- spdlog::debug("MSI installer extracted to {}", installerPath->string());
- }
- else
- {
- spdlog::error("MSI installer couldn't be extracted");
- }
-
- return 0;
- }
-
- const VersionHelper myVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
-
- // Do not support installing on Windows < 1903
- if (!Is19H1OrHigher())
- {
- ShowMessageBoxError(IDS_OLD_WINDOWS_ERROR);
- spdlog::error("PowerToys {} requires at least Windows 1903 to run.", myVersion.toString());
- return 1;
- }
-
- // Check if there's a newer version installed
- const auto installedVersionInfo = get_installed_powertoys_version();
- if (installedVersionInfo)
- {
- if (installedVersionInfo->version >= myVersion)
- {
- spdlog::error(L"Detected a newer version {} vs {}", installedVersionInfo->version.toWstring(), myVersion.toWstring());
- ShowMessageBoxError(IDS_NEWER_VERSION_ERROR);
- return 0;
- }
- // If we are good to go and install folder wasn't specified via cmd line, make sure to retain the previous
- // installation path
- else if (installFolderProp.empty())
- {
- installFolderProp = L"INSTALLFOLDER=\"" + installedVersionInfo->install_folder + L"\"";
- }
- }
-
- // Always elevate bootstrapper process since it invokes msiexec multiple times,
- // so we can avoid multiple UAC confirmations
- if (!is_process_elevated())
- {
- ReLaunchElevatedAndExit();
- }
-
- // Setup MSI UI visibility
- if (!noFullUI)
- {
- MsiSetInternalUI(INSTALLUILEVEL_FULL, nullptr);
- }
-
- if (g_Silent)
- {
- MsiSetInternalUI(INSTALLUILEVEL_NONE, nullptr);
- }
-
- // Try killing PowerToys and prevent future processes launch by acquiring app mutex
- for (auto& handle : getProcessHandlesByName(L"PowerToys.exe", PROCESS_TERMINATE))
- {
- TerminateProcess(handle.get(), 0);
- }
-
- auto powerToysMutex = createAppMutex(POWERTOYS_MSI_MUTEX_NAME);
- auto instanceMutex = createAppMutex(POWERTOYS_BOOTSTRAPPER_MUTEX_NAME);
- if (!instanceMutex)
- {
- spdlog::error("Couldn't acquire PowerToys global mutex. Setup couldn't terminate PowerToys.exe process");
- return 1;
- }
-
- spdlog::debug("Extracting embedded MSI installer");
- const auto installerPath = ExtractEmbeddedInstaller(fs::temp_directory_path());
- if (!installerPath)
- {
- ShowMessageBoxError(IDS_INSTALLER_EXTRACT_ERROR);
- spdlog::error("Couldn't install the MSI installer ({})", GetLastError());
- return 1;
- }
-
- auto removeExtractedInstaller = wil::scope_exit([&] {
- std::error_code _;
- fs::remove(*installerPath, _);
- });
-
- spdlog::debug("Acquiring existing MSI package path if exists");
- const auto package_path = GetMsiPackagePath();
- if (!package_path.empty())
- {
- spdlog::debug(L"Existing MSI package path found: {}", package_path);
- }
- else
- {
- spdlog::debug("Existing MSI package path not found");
- }
-
- if (!package_path.empty() && !uninstall_msi_version(package_path))
- {
- spdlog::error("Couldn't uninstall the existing MSI package ({})", GetLastError());
- ShowMessageBoxError(IDS_UNINSTALL_PREVIOUS_VERSION_ERROR);
- return 1;
- }
-
- const bool installDotnet = !skipDotnetInstall;
- if (!g_Silent)
- {
- OpenProgressBarDialog(hInstance, 0, GET_RESOURCE_STRING(IDS_BOOTSTRAPPER_PROGRESS_TITLE).c_str(), GET_RESOURCE_STRING(IDS_DOWNLOADING_DOTNET).c_str());
- }
-
- try
- {
- if (installDotnet)
- {
- spdlog::debug("Detecting if dotnet is installed");
- const bool dotnetInstalled = updating::dotnet_is_installed();
- spdlog::debug("Dotnet is already installed: {}", dotnetInstalled);
- if (!dotnetInstalled)
- {
- bool installedSuccessfully = false;
- if (const auto dotnet_installer_path = updating::download_dotnet())
- {
- // Dotnet installer has its own progress bar
- CloseProgressBarDialog();
- installedSuccessfully = updating::install_dotnet(*dotnet_installer_path, g_Silent);
- if (!installedSuccessfully)
- {
- spdlog::error("Couldn't install dotnet");
- }
- }
- else
- {
- spdlog::error("Couldn't download dotnet");
- }
-
- if (!installedSuccessfully)
- {
- ShowMessageBoxError(IDS_DOTNET_INSTALL_ERROR);
- }
- }
- }
- }
- catch (...)
- {
- spdlog::error("Unknown exception during dotnet installation");
- ShowMessageBoxError(IDS_DOTNET_INSTALL_ERROR);
- }
-
- // At this point, there's no reason to show progress bar window, since MSI installers have their own
- CloseProgressBarDialog();
-
- const std::wstring msiProps = installFolderProp;
- spdlog::debug("Launching MSI installation for new package {}", installerPath->string());
- const bool installationDone = MsiInstallProductW(installerPath->c_str(), msiProps.c_str()) == ERROR_SUCCESS;
- if (!installationDone)
- {
- spdlog::error("Couldn't install new MSI package ({})", GetLastError());
- return 1;
- }
-
- spdlog::debug("Installation completed");
-
- if ((!noStartPT && !g_Silent) || startPT)
- {
- spdlog::debug("Starting the newly installed PowerToys.exe");
- auto newPTPath = GetMsiPackageInstalledPath();
- if (!newPTPath)
- {
- spdlog::error("Couldn't determine new MSI package install location ({})", GetLastError());
- return 1;
- }
-
- *newPTPath += L"\\PowerToys.exe";
- SHELLEXECUTEINFOW sei{ sizeof(sei) };
- sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NO_CONSOLE };
- sei.lpFile = newPTPath->c_str();
- sei.nShow = SW_SHOWNORMAL;
- ShellExecuteExW(&sei);
- }
-
- return 0;
-}
-
-int WINAPI WinMain(HINSTANCE hi, HINSTANCE, LPSTR, int)
-{
- try
- {
- return Bootstrapper(hi);
- }
- catch (const std::exception& ex)
- {
- std::string messageA{ "Unhandled std exception encountered\n" };
- messageA.append(ex.what());
-
- spdlog::error(messageA.c_str());
-
- std::wstring messageW{};
- std::copy(messageA.begin(), messageA.end(), messageW.begin());
- ShowMessageBoxError(messageW.c_str());
- }
- catch (winrt::hresult_error const& ex)
- {
- std::wstring message{ L"Unhandled winrt exception encountered\n" };
- message.append(ex.message().c_str());
-
- spdlog::error(message.c_str());
-
- ShowMessageBoxError(message.c_str());
- }
- catch (...)
- {
- auto lastErrorMessage = get_last_error_message(GetLastError());
- std::wstring message{ L"Unknown exception encountered\n" };
- message.append(lastErrorMessage ? std::move(*lastErrorMessage) : L"");
-
- spdlog::error(message.c_str());
-
- ShowMessageBoxError(message.c_str());
- }
- return 0;
-}
diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj
deleted file mode 100644
index e1417ef739..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj
+++ /dev/null
@@ -1,157 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
-
-
-
- 16.0
- {D194E3AA-F824-4CA9-9A58-034DD6B7D022}
- bootstrapper
- true
- 10.0.18362.0
- 10.0.18362.0
- bootstrapper
-
-
-
-
-
- Application
- true
- v142
- Unicode
- Spectre
-
-
- Application
- false
- v142
- true
- Unicode
- Spectre
-
-
-
-
-
-
-
-
-
-
-
-
-
- PowerToysSetup-$(Version)-$(PlatformShortName)
-
-
- false
- ../;$(IncludePath)
- $(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\
-
-
- true
- ../;$(IncludePath)
- $(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\
-
-
-
- Level3
- true
- true
- true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
- MultiThreaded
- true
- ../../../src/;%(AdditionalIncludeDirectories)
- Use
- pch.h
- /await /Zc:twoPhase- %(AdditionalOptions)
-
-
- Windows
- true
- true
- true
- WindowsApp.lib;Msi.lib;Shlwapi.lib;Comctl32.lib;Version.lib;%(AdditionalDependencies)
-
-
-
-
- Level3
- true
- _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- MultiThreadedDebug
- true
- ../../../src/;%(AdditionalIncludeDirectories)
- Use
- pch.h
- /await /Zc:twoPhase- %(AdditionalOptions)
-
-
- Windows
- true
- WindowsApp.lib;Msi.lib;Shlwapi.lib;Comctl32.lib;Version.lib;%(AdditionalDependencies)
-
-
-
-
-
-
- Create
- Create
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {6955446d-23f7-4023-9bb3-8657f904af99}
-
-
- {cc6e41ac-8174-4e8a-8d22-85dd7f4851df}
-
-
- {7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f}
-
-
-
-
-
-
-
-
- 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}.
-
-
-
-
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/packages.config b/installer/PowerToysBootstrapper/bootstrapper/packages.config
deleted file mode 100644
index 26065b144b..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/pch.cpp b/installer/PowerToysBootstrapper/bootstrapper/pch.cpp
deleted file mode 100644
index 17305716aa..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/pch.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "pch.h"
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/pch.h b/installer/PowerToysBootstrapper/bootstrapper/pch.h
deleted file mode 100644
index d305b41917..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/pch.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#define NOMINMAX
-#define WIN32_LEAN_AND_MEAN
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#pragma warning(push, 0)
-#include
-#include
-#include
-#pragma warning(pop)
-
-#include
diff --git a/installer/PowerToysBootstrapper/bootstrapper/progressbar_window.cpp b/installer/PowerToysBootstrapper/bootstrapper/progressbar_window.cpp
deleted file mode 100644
index 78ee2a5412..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/progressbar_window.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-#include "pch.h"
-
-#include
-
-#include "progressbar_window.h"
-#include "Generated Files/resource.h"
-
-const int labelHeight = 18;
-
-const int progressBarHeight = 20;
-const int margin = 10;
-
-const int windowWidth = 480;
-const int titleBarHeight = 32;
-const int windowHeight = margin * 4 + progressBarHeight + labelHeight + titleBarHeight;
-
-int progressBarSteps = 0;
-
-HWND hDialog = nullptr;
-HWND hLabel = nullptr;
-HWND hProgressBar = nullptr;
-HBRUSH hBrush = nullptr;
-
-std::wstring labelText;
-std::mutex uiThreadIsRunning;
-
-namespace nonlocalized
-{
- const wchar_t windowClass[] = L"PTBProgressBarWnd";
- const wchar_t labelClass[] = L"static";
-}
-
-#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- switch (Msg)
- {
- case WM_CREATE:
- {
- uiThreadIsRunning.lock();
-
- hLabel = CreateWindowW(nonlocalized::labelClass,
- labelText.c_str(),
- WS_CHILD | WS_VISIBLE | WS_TABSTOP,
- margin,
- margin,
- windowWidth - (margin * 4),
- labelHeight,
- hWnd,
- (HMENU)(501),
- (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE), nullptr);
-
- hProgressBar = CreateWindowExW(0,
- PROGRESS_CLASS,
- nullptr,
- WS_VISIBLE | WS_CHILD | PBS_SMOOTH,
- margin,
- (margin * 2) + labelHeight,
- windowWidth - (margin * 4),
- progressBarHeight,
- hWnd,
- (HMENU)(IDR_PROGRESS_BAR),
- (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE),
- nullptr);
-
- bool filledOnStart = false;
- if (progressBarSteps == 0)
- {
- progressBarSteps = 1;
- filledOnStart = true;
- }
-
- SendMessageW(hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, progressBarSteps));
- SendMessageW(hProgressBar, PBM_SETSTEP, 1, 0);
-
- if (filledOnStart)
- {
- SendMessageW(hProgressBar, PBM_STEPIT, 0, 0);
- }
-
- break;
- }
- case WM_CTLCOLORSTATIC:
- {
- if (lParam == (LPARAM)hLabel)
- {
- if (!hBrush)
- {
- HDC hdcStatic = (HDC)wParam;
- SetTextColor(hdcStatic, RGB(0, 0, 0));
- SetBkColor(hdcStatic, RGB(255, 255, 255));
- hBrush = CreateSolidBrush(RGB(255, 255, 255));
- }
-
- return (LRESULT)hBrush;
- }
- break;
- }
- case WM_CLOSE:
- {
- DestroyWindow(hWnd);
- PostQuitMessage(0);
- break;
- }
- default:
- {
- return DefWindowProcW(hWnd, Msg, wParam, lParam);
- }
- }
- return 0;
-}
-
-void OpenProgressBarDialog(HINSTANCE hInstance, const int nProgressbarSteps, const wchar_t* title, const wchar_t* label)
-{
- labelText = label;
- progressBarSteps = nProgressbarSteps;
- std::wstring window_title{ title };
- std::thread{
- [hInstance, window_title = std::move(window_title)] {
- INITCOMMONCONTROLSEX iccex{.dwSize = sizeof(iccex), .dwICC = ICC_NATIVEFNTCTL_CLASS | ICC_PROGRESS_CLASS };
- InitCommonControlsEx(&iccex);
-
- WNDCLASSEX wc{};
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.lpfnWndProc = WndProc;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDR_BIN_ICON));
- wc.hIconSm = LoadIconW(hInstance, MAKEINTRESOURCE(IDR_BIN_ICON));
- wc.lpszClassName = nonlocalized::windowClass;
-
- if (!RegisterClassExW(&wc))
- {
- spdlog::warn("Couldn't register main_window class for progress bar.");
- return;
- }
-
- RECT rect{};
- GetClientRect(GetDesktopWindow(), &rect);
- rect.left = rect.right / 2 - windowWidth / 2;
- rect.top = rect.bottom / 4 - windowHeight / 2;
- hDialog = CreateWindowExW(WS_EX_CLIENTEDGE,
- nonlocalized::windowClass,
- window_title.c_str(),
- WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX,
- rect.left,
- rect.top,
- windowWidth,
- windowHeight,
- nullptr,
- nullptr,
- hInstance,
- nullptr);
-
- if (!hDialog)
- {
- spdlog::warn("Couldn't create progress bar main_window");
- return;
- }
-
- ShowWindow(hDialog, SW_SHOW);
- UpdateWindow(hDialog);
- run_message_loop();
- uiThreadIsRunning.unlock();
- }
- }.detach();
-}
-
-void UpdateProgressBarDialog(const wchar_t* label)
-{
- SetWindowTextW(hLabel, label);
- SendMessageW(hProgressBar, PBM_STEPIT, 0, 0);
-}
-
-void CloseProgressBarDialog()
-{
- SendMessageW(hDialog, WM_CLOSE, {}, {});
- {
- std::unique_lock waitForUIToExit{ uiThreadIsRunning };
- }
-
- // Return focus to the current process, since it was lost due to progress bar closing (?)
- INPUT i = {INPUT_MOUSE, {}};
- SendInput(1, &i, sizeof(i));
- SetForegroundWindow(GetActiveWindow());
-
-}
\ No newline at end of file
diff --git a/installer/PowerToysBootstrapper/bootstrapper/progressbar_window.h b/installer/PowerToysBootstrapper/bootstrapper/progressbar_window.h
deleted file mode 100644
index 22aa90e358..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/progressbar_window.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#define NOMINMAX
-#define WIN32_LEAN_AND_MEAN
-#include
-
-void OpenProgressBarDialog(HINSTANCE hInstance, const int nProgressbarSteps, const wchar_t* title, const wchar_t* label);
-void UpdateProgressBarDialog(const wchar_t* label);
-void CloseProgressBarDialog();
diff --git a/installer/PowerToysBootstrapper/bootstrapper/resource.base.h b/installer/PowerToysBootstrapper/bootstrapper/resource.base.h
deleted file mode 100644
index 49b371996c..0000000000
--- a/installer/PowerToysBootstrapper/bootstrapper/resource.base.h
+++ /dev/null
@@ -1,17 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by bootstrapper.rc
-
-//////////////////////////////
-// Non-localizable
-
-#define FILE_DESCRIPTION "PowerToys Bootstrapper"
-#define INTERNAL_NAME "bootstrapper"
-#define ORIGINAL_FILENAME "bootstrapper.exe"
-
-// Non-localizable
-//////////////////////////////
-
-#define IDR_BIN_MSIINSTALLER 103
-#define IDR_BIN_ICON 104
-#define IDR_PROGRESS_BAR 105
diff --git a/installer/PowerToysSetup.sln b/installer/PowerToysSetup.sln
index cd095d5369..15ec0116d6 100644
--- a/installer/PowerToysSetup.sln
+++ b/installer/PowerToysSetup.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysSetup", "PowerToysSetup\PowerToysSetup.wixproj", "{022A9D30-7C4F-416D-A9DF-5FF2661CC0AD}"
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysInstaller", "PowerToysSetup\PowerToysInstaller.wixproj", "{022A9D30-7C4F-416D-A9DF-5FF2661CC0AD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToysSetupCustomActions", "PowerToysSetupCustomActions\PowerToysSetupCustomActions.vcxproj", "{32F3882B-F2D6-4586-B5ED-11E39E522BD3}"
EndProject
@@ -11,6 +11,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "..\src\logging\lo
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logger", "..\src\common\logger\logger.vcxproj", "{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}"
EndProject
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysBootstrapper", "PowerToysSetup\PowerToysBootstrapper.wixproj", "{31D72625-43C1-41B1-B784-BCE4A8DC5543}"
+ ProjectSection(ProjectDependencies) = postProject
+ {022A9D30-7C4F-416D-A9DF-5FF2661CC0AD} = {022A9D30-7C4F-416D-A9DF-5FF2661CC0AD}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -33,6 +38,10 @@ Global
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Debug|x64.Build.0 = Debug|x64
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Release|x64.ActiveCfg = Release|x64
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Release|x64.Build.0 = Release|x64
+ {31D72625-43C1-41B1-B784-BCE4A8DC5543}.Debug|x64.ActiveCfg = Debug|x64
+ {31D72625-43C1-41B1-B784-BCE4A8DC5543}.Debug|x64.Build.0 = Debug|x64
+ {31D72625-43C1-41B1-B784-BCE4A8DC5543}.Release|x64.ActiveCfg = Release|x64
+ {31D72625-43C1-41B1-B784-BCE4A8DC5543}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/installer/PowerToysSetup/PowerToys.wxs b/installer/PowerToysSetup/PowerToys.wxs
new file mode 100644
index 0000000000..31d6292454
--- /dev/null
+++ b/installer/PowerToysSetup/PowerToys.wxs
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TargetPowerToysVersion >= DetectedPowerToysVersion OR WixBundleInstalled
+
+
+
+ DetectedWindowsBuildNumber >= 18362 OR WixBundleInstalled
+
+
+
+
+
+
+
+
+
+
+
diff --git a/installer/PowerToysSetup/PowerToysBootstrapper.wixproj b/installer/PowerToysSetup/PowerToysBootstrapper.wixproj
new file mode 100644
index 0000000000..ec87a8f8c2
--- /dev/null
+++ b/installer/PowerToysSetup/PowerToysBootstrapper.wixproj
@@ -0,0 +1,67 @@
+
+
+
+
+
+ Version=$(Version)
+ PowerToysBootstrapper
+ {31d72625-43c1-41b1-b784-bce4a8dc5543}
+
+
+ Release
+ x64
+ 3.10
+ 2.0
+ PowerToysSetup-$(Version)-$(Platform)
+ Bundle
+ True
+
+
+
+
+ $(Platform)\$(Configuration)\
+ obj\$(Platform)\$(Configuration)\
+
+
+ $(Platform)\$(Configuration)\
+ obj\$(Platform)\$(Configuration)\
+
+
+
+
+
+
+ $(WixExtDir)\WixUtilExtension.dll
+ WixUtilExtension
+
+
+ $(WixExtDir)\WixUIExtension.dll
+ WixUIExtension
+
+
+ $(WixExtDir)\WixNetFxExtension.dll
+ WixNetFxExtension
+
+
+ $(WixExtDir)\WixBalExtension.dll
+ WixBalExtension
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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}.
+
+
+
+
\ No newline at end of file
diff --git a/installer/PowerToysSetup/PowerToysSetup.wixproj b/installer/PowerToysSetup/PowerToysInstaller.wixproj
similarity index 93%
rename from installer/PowerToysSetup/PowerToysSetup.wixproj
rename to installer/PowerToysSetup/PowerToysInstaller.wixproj
index c056b393bf..b80af7ca42 100644
--- a/installer/PowerToysSetup/PowerToysSetup.wixproj
+++ b/installer/PowerToysSetup/PowerToysInstaller.wixproj
@@ -4,6 +4,7 @@
Version=$(Version)
+ PowerToysInstaller
Release
@@ -20,10 +21,14 @@
$(Platform)\$(Configuration)\
obj\$(Platform)\$(Configuration)\
+ ICE91
+ True
$(Platform)\$(Configuration)\
obj\$(Platform)\$(Configuration)\
+ True
+ ICE91
diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs
index fdfb02fdfd..4bdadab54c 100644
--- a/installer/PowerToysSetup/Product.wxs
+++ b/installer/PowerToysSetup/Product.wxs
@@ -2,23 +2,23 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
-
- = 18362)]]>
-
+
+
+
+
+ = 18362)]]>
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
- NOT Installed
- 1
- NOT Installed
- NOT Installed
- Installed AND _REMOVE_ALL="Yes"
- Installed AND _REMOVE_ALL="Yes"
- Installed AND NOT (_REMOVE_ALL="Yes")
- Installed AND NOT (_REMOVE_ALL="Yes")
-
-
-
-
-
-
-
+
+
+
+ 1
+ 1
-
-
-
-
-
-
-
-
- NOT Installed and CREATESCHEDULEDTASK = 1
-
-
- NOT Installed
-
-
-
-
-
+
+
+
+
+
+ ""]]>
+
+
+ DEFAULTBOOTSTRAPPERINSTALLFOLDER OR PREVIOUSINSTALLFOLDER = ""]]>
+
+
+
+
+
+
+
+
+ NOT Installed and CREATESCHEDULEDTASK = 1
+
+
+ NOT Installed
+
+
+
+
+
-
- NOT Installed
-
-
- Installed and (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
-
-
- Installed AND (REMOVE="ALL")
-
+
+ NOT Installed
+
+
+ Installed and (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
+
+
+ Installed AND (REMOVE="ALL")
+
-
-
+
-
+
-
+ NOT Installed
-
+
-
+
-
+
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- WINDOWSBUILDNUMBER >= 18362
-
-
-
-
-
-
-
-
-
-
-
- WINDOWSBUILDNUMBER >= 18362
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- INSTALLDESKTOPSHORTCUT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WINDOWSBUILDNUMBER >= 18362
+
+
+
+
+
+
+
+ WINDOWSBUILDNUMBER >= 18362
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INSTALLDESKTOPSHORTCUT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp
index b858a35cb9..ece9d8da2a 100644
--- a/installer/PowerToysSetupCustomActions/CustomAction.cpp
+++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "resource.h"
+#include "RcResource.h"
#include
#include
@@ -10,8 +11,6 @@
#include "../../src/common/updating/installer.h"
#include "../../src/common/version/version.h"
-#include "../../installer/PowerToysBootstrapper/bootstrapper/RcResource.h"
-
using namespace std;
HINSTANCE DLL_HANDLE = nullptr;
@@ -76,7 +75,7 @@ UINT __stdcall ApplyModulesRegistryChangeSetsCA(MSIHANDLE hInstall)
hr = getInstallFolder(hInstall, installationFolder);
ExitOnFailure(hr, "Failed to get installFolder.");
- for (const auto& changeSet : getAllModulesChangeSets(installationFolder, false))
+ for (const auto& changeSet : getAllModulesChangeSets(installationFolder))
{
if (!changeSet.apply())
{
@@ -105,7 +104,7 @@ UINT __stdcall UnApplyModulesRegistryChangeSetsCA(MSIHANDLE hInstall)
ExitOnFailure(hr, "Failed to initialize");
hr = getInstallFolder(hInstall, installationFolder);
ExitOnFailure(hr, "Failed to get installFolder.");
- for (const auto& changeSet : getAllModulesChangeSets(installationFolder, false))
+ for (const auto& changeSet : getAllModulesChangeSets(installationFolder))
{
changeSet.unApply();
}
@@ -748,12 +747,12 @@ UINT __stdcall DetectPrevInstallPathCA(MSIHANDLE hInstall)
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
hr = WcaInitialize(hInstall, "DetectPrevInstallPathCA");
-
+ MsiSetPropertyW(hInstall, L"PREVIOUSINSTALLFOLDER", L"");
try
{
if (auto install_path = GetMsiPackageInstalledPath())
{
- MsiSetPropertyW(hInstall, L"INSTALLFOLDER", install_path->data());
+ MsiSetPropertyW(hInstall, L"PREVIOUSINSTALLFOLDER", install_path->data());
}
}
catch (...)
diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj
index 935e5b7994..b2883566b6 100644
--- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj
+++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj
@@ -16,6 +16,7 @@
Win32Proj
PowerToysSetupCustomActions
10.0.18362.0
+ PowerToysSetupCustomActions
@@ -53,12 +54,12 @@
- inc;..\..\src\;telemetry;$(WIX)sdk\$(WixPlatformToolset)\inc;$(SolutionDir)\packages\WiX.3.11.2\tools\sdk\inc;%(AdditionalIncludeDirectories)
+ inc;..\..\src\;..\..\src\common\Telemetry;telemetry;$(WIX)sdk\$(WixPlatformToolset)\inc;$(SolutionDir)\packages\WiX.3.11.2\tools\sdk\inc;%(AdditionalIncludeDirectories)
/await /Zc:twoPhase- /Wv:18 %(AdditionalOptions)
- $(WIX)sdk\$(WixPlatformToolset)\lib\x64;$(SolutionDir)\packages\WiX.3.11.2\tools\sdk\vs2017\lib\x64;..\..\$(PlatformShortName)\$(Configuration)\;%(AdditionalLibraryDirectories)
- WindowsApp.lib;Newdev.lib;Crypt32.lib;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)
+ $(WIX)sdk\$(WixPlatformToolset)\lib\x64;$(SolutionDir)\packages\WiX.3.11.2\tools\sdk\vs2017\lib\x64;%(AdditionalLibraryDirectories)
+ WindowsApp.lib;Newdev.lib;Crypt32.lib;msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;Shlwapi.lib;%(AdditionalDependencies)
@@ -114,7 +115,7 @@
-
+
diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj.filters b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj.filters
index 85074f6e16..7108f08409 100644
--- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj.filters
+++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj.filters
@@ -13,7 +13,7 @@
Telemetry
-
+
diff --git a/installer/PowerToysBootstrapper/bootstrapper/RcResource.h b/installer/PowerToysSetupCustomActions/RcResource.h
similarity index 100%
rename from installer/PowerToysBootstrapper/bootstrapper/RcResource.h
rename to installer/PowerToysSetupCustomActions/RcResource.h
diff --git a/src/Update/PowerToys.Update.cpp b/src/Update/PowerToys.Update.cpp
index 13c7a11b5c..a7ddecf982 100644
--- a/src/Update/PowerToys.Update.cpp
+++ b/src/Update/PowerToys.Update.cpp
@@ -148,22 +148,12 @@ bool InstallNewVersionStage2(std::wstring installer_path, std::wstring_view inst
}
else
{
- // If it's not .msi, then it's our .exe installer
+ // If it's not .msi, then it's a wix bootstrapper
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";
- }
-
+ std::wstring parameters = L"/passive";
sei.lpParameters = parameters.c_str();
success = ShellExecuteExW(&sei) == TRUE;
diff --git a/src/common/utils/modulesRegistry.h b/src/common/utils/modulesRegistry.h
index 37d7082d9c..158fb0e5d7 100644
--- a/src/common/utils/modulesRegistry.h
+++ b/src/common/utils/modulesRegistry.h
@@ -106,13 +106,14 @@ inline registry::ChangeSet getGcodeThumbnailHandlerChangeSet(const std::wstring
L".gcode");
}
-inline std::vector getAllModulesChangeSets(const std::wstring installationDir, const bool perUser)
+inline std::vector getAllModulesChangeSets(const std::wstring installationDir)
{
- return { getSvgPreviewHandlerChangeSet(installationDir, perUser),
- getMdPreviewHandlerChangeSet(installationDir, perUser),
- getPdfPreviewHandlerChangeSet(installationDir, perUser),
- getGcodePreviewHandlerChangeSet(installationDir, perUser),
- getSvgThumbnailHandlerChangeSet(installationDir, perUser),
- getPdfThumbnailHandlerChangeSet(installationDir, perUser),
- getGcodeThumbnailHandlerChangeSet(installationDir, perUser) };
+ constexpr bool PER_USER = true;
+ return { getSvgPreviewHandlerChangeSet(installationDir, PER_USER),
+ getMdPreviewHandlerChangeSet(installationDir, PER_USER),
+ getPdfPreviewHandlerChangeSet(installationDir, PER_USER),
+ getGcodePreviewHandlerChangeSet(installationDir, PER_USER),
+ getSvgThumbnailHandlerChangeSet(installationDir, PER_USER),
+ getPdfThumbnailHandlerChangeSet(installationDir, PER_USER),
+ getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER) };
}
\ No newline at end of file
diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp
index 138fb08f44..a0bbd6f43c 100644
--- a/src/modules/previewpane/powerpreview/powerpreview.cpp
+++ b/src/modules/previewpane/powerpreview/powerpreview.cpp
@@ -25,7 +25,7 @@ PowerPreviewModule::PowerPreviewModule() :
Logger::init(LogSettings::fileExplorerLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
Logger::info("Initializing PowerPreviewModule");
- const bool installPerUser = false;
+ const bool installPerUser = true;
m_fileExplorerModules.push_back({ .settingName = L"svg-previewer-toggle-setting",
.settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION),
.registryChanges = getSvgPreviewHandlerChangeSet(installationDir, installPerUser) });
@@ -49,7 +49,7 @@ PowerPreviewModule::PowerPreviewModule() :
m_fileExplorerModules.push_back({ .settingName = L"pdf-thumbnail-toggle-setting",
.settingDescription = GET_RESOURCE_STRING(IDS_PDF_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
.registryChanges = getPdfThumbnailHandlerChangeSet(installationDir, installPerUser) });
-
+
m_fileExplorerModules.push_back({ .settingName = L"gcode-thumbnail-toggle-setting",
.settingDescription = GET_RESOURCE_STRING(IDS_GCODE_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
.registryChanges = getGcodeThumbnailHandlerChangeSet(installationDir, installPerUser) });
@@ -144,21 +144,13 @@ void PowerPreviewModule::enable()
// Disable active preview handlers.
void PowerPreviewModule::disable()
{
- // Check if the process is elevated in order to have permissions to modify HKLM registry
- if (is_process_elevated(false))
+ for (auto& fileExplorerModule : m_fileExplorerModules)
{
- for (auto& fileExplorerModule : m_fileExplorerModules)
+ if (!fileExplorerModule.registryChanges.unApply())
{
- if (!fileExplorerModule.registryChanges.unApply())
- {
- Logger::error(L"Couldn't disable file explorer module {} during module disable() call", fileExplorerModule.settingName);
- }
+ Logger::error(L"Couldn't disable file explorer module {} during module disable() call", fileExplorerModule.settingName);
}
}
- else
- {
- show_update_warning_message();
- }
if (m_enabled)
{
@@ -197,9 +189,7 @@ void PowerPreviewModule::show_update_warning_message()
void PowerPreviewModule::apply_settings(const PowerToysSettings::PowerToyValues& settings)
{
- const bool isElevated = is_process_elevated(false);
bool notifyShell = false;
- bool updatesNeeded = false;
for (auto& fileExplorerModule : m_fileExplorerModules)
{
@@ -210,11 +200,6 @@ void PowerPreviewModule::apply_settings(const PowerToysSettings::PowerToyValues&
{
continue;
}
- else
- {
- // Mark that updates were to the registry were needed
- updatesNeeded = true;
- }
// (Un)Apply registry changes depending on the new setting value
const bool updated = *toggle ? fileExplorerModule.registryChanges.apply() : fileExplorerModule.registryChanges.unApply();
@@ -230,10 +215,6 @@ void PowerPreviewModule::apply_settings(const PowerToysSettings::PowerToyValues&
Trace::PowerPreviewSettingsUpdateFailed(fileExplorerModule.settingName.c_str(), !*toggle, *toggle, true);
}
}
- if (!isElevated && updatesNeeded)
- {
- show_update_warning_message();
- }
if (notifyShell)
{
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
index d9ec0ed28d..10ba89fa02 100644
--- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
+++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
@@ -1006,9 +1006,6 @@ Made with 💗 by Microsoft and the PowerToys community.
You need to run as administrator to modify these settings.
-
- The settings on this page affect all users on the system
-
A reboot may be required for changes to these settings to take effect
diff --git a/src/settings-ui/Settings.UI/Views/PowerPreviewPage.xaml b/src/settings-ui/Settings.UI/Views/PowerPreviewPage.xaml
index c5102b0032..488d41449b 100644
--- a/src/settings-ui/Settings.UI/Views/PowerPreviewPage.xaml
+++ b/src/settings-ui/Settings.UI/Views/PowerPreviewPage.xaml
@@ -20,25 +20,10 @@
-
-
-
-
@@ -46,7 +31,6 @@
@@ -54,7 +38,6 @@
@@ -62,7 +45,6 @@
@@ -78,7 +60,6 @@
@@ -86,7 +67,6 @@
@@ -94,7 +74,6 @@
@@ -107,4 +86,4 @@
-
\ No newline at end of file
+