diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 6a389cab2c..d99ef2c045 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -2006,6 +2006,7 @@ swprintf SWRESTORE swscanf SYMED +symlink SYMOPT SYNCMFT SYNCPAINT diff --git a/installer/PowerToysSetup/PowerToys.wxs b/installer/PowerToysSetup/PowerToys.wxs index 10a90dcda6..37ea295681 100644 --- a/installer/PowerToysSetup/PowerToys.wxs +++ b/installer/PowerToysSetup/PowerToys.wxs @@ -10,10 +10,6 @@ - - - - @@ -24,10 +20,6 @@ - - - - @@ -69,8 +61,6 @@ DetectedWindowsBuildNumber >= 19041 OR WixBundleInstalled - - - - - - - + - + - + @@ -113,19 +113,23 @@ - + - + + + + + - + + + + + NOT Installed and CREATESCHEDULEDTASK = 1 NOT Installed + + NOT Installed + + + NOT Installed + @@ -244,6 +258,12 @@ Installed AND (REMOVE="ALL") + + Installed AND (REMOVE="ALL") + + + Installed AND (REMOVE="ALL") + + + + + + + + + - @@ -415,6 +482,10 @@ + + + + @@ -617,9 +688,6 @@ - - - @@ -669,6 +737,22 @@ + + + + + + + + + + + + + + + + @@ -906,7 +990,7 @@ - + @@ -926,7 +1010,7 @@ - + @@ -936,7 +1020,7 @@ - + @@ -1089,7 +1173,6 @@ - @@ -1168,6 +1251,12 @@ + + + + + + @@ -1828,7 +1917,7 @@ - + diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index 764b1a0067..57df075882 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -32,6 +32,56 @@ const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0' static const wchar_t* POWERTOYS_EXE_COMPONENT = L"{A2C66D91-3485-4D00-B04D-91844E6B345B}"; static const wchar_t* POWERTOYS_UPGRADE_CODE = L"{42B84BF7-5FBF-473B-9C8B-049DC16F7708}"; +const std::vector winAppSdkFiles = { + L"CoreMessagingXP.dll", + L"DWriteCore.dll", + L"DwmSceneI.dll", + L"MRM.dll", + L"Microsoft.DirectManipulation.dll", + L"Microsoft.InputStateManager.dll", + L"Microsoft.Internal.FrameworkUdk.dll", + L"Microsoft.UI.Composition.OSSupport.dll", + L"Microsoft.UI.Input.dll", + L"Microsoft.UI.Windowing.Core.dll", + L"Microsoft.UI.Xaml.Controls.dll", + L"Microsoft.UI.Xaml.Controls.pri", + L"Microsoft.UI.Xaml.Internal.dll", + L"Microsoft.UI.Xaml.Phone.dll", + L"Microsoft.Web.WebView2.Core.dll", + L"Microsoft.Windows.AppNotifications.Projection.dll", + L"Microsoft.Windows.ApplicationModel.Resources.dll", + L"Microsoft.WindowsAppRuntime.Bootstrap.dll", + L"Microsoft.Windows.PushNotifications.Projection.dll", + L"Microsoft.Windows.System.Projection.dll", + L"Microsoft.WindowsAppRuntime.Insights.Resource.dll", + L"Microsoft.WindowsAppRuntime.Release.Net.dll", + L"Microsoft.WindowsAppRuntime.dll", + L"Microsoft.ui.xaml.dll", + L"Microsoft.ui.xaml.resources.19h1.dll", + L"Microsoft.ui.xaml.resources.common.dll", + L"PushNotificationsLongRunningTask.ProxyStub.dll", + L"WinUIEdit.dll", + L"WindowsAppRuntime.png", + L"WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll", + L"dcompi.dll", + L"dwmcorei.dll", + L"marshal.dll", + L"wuceffectsi.dll" }; + +const std::vector powerToysInteropFiles = { + L"concrt140.dll", + L"msvcp140.dll", + L"msvcp140_1.dll", + L"msvcp140_2.dll", + L"msvcp140_atomic_wait.dll", + L"msvcp140_codecvt_ids.dll", + L"PowerToys.Interop.dll", + L"vcamp140.dll", + L"vccorlib140.dll", + L"vcomp140.dll", + L"vcruntime140.dll", + L"vcruntime140_1.dll" }; + struct WcaSink : spdlog::sinks::base_sink { virtual void sink_it_(const spdlog::details::log_msg& msg) override @@ -995,6 +1045,181 @@ UINT __stdcall UnRegisterContextMenuPackagesCA(MSIHANDLE hInstall) return WcaFinalize(er); } +UINT __stdcall CreateWinAppSDKHardlinksCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + std::wstring installationFolder, winAppSDKFilesSrcDir, settingsDir, powerRenameDir; + + hr = WcaInitialize(hInstall, "CreateWinAppSDKHardlinksCA"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = getInstallFolder(hInstall, installationFolder); + ExitOnFailure(hr, "Failed to get installation folder"); + + winAppSDKFilesSrcDir = installationFolder + L"dll\\WinAppSDK\\"; + settingsDir = installationFolder + L"Settings\\"; + powerRenameDir = installationFolder + L"modules\\PowerRename\\"; + + for (auto file : winAppSdkFiles) + { + std::error_code ec; + std::filesystem::create_hard_link((winAppSDKFilesSrcDir + file).c_str(), (settingsDir + file).c_str(), ec); + std::filesystem::create_hard_link((winAppSDKFilesSrcDir + file).c_str(), (powerRenameDir + file).c_str(), ec); + + if (ec.value() != S_OK) + { + std::wstring errorMessage{ L"Error creating hard link for: " }; + errorMessage += file; + errorMessage += L", error code: " + std::to_wstring(ec.value()); + Logger::error(errorMessage); + } + } + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +UINT __stdcall CreatePTInteropHardlinksCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + std::wstring installationFolder, interopFilesSrcDir, colorPickerDir, powerOCRDir, launcherDir, fancyZonesDir, + imageResizerDir, settingsDir, awakeDir, measureToolDir, powerAccentDir; + + hr = WcaInitialize(hInstall, "CreatePTInteropHardlinksCA"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = getInstallFolder(hInstall, installationFolder); + ExitOnFailure(hr, "Failed to get installation folder"); + + interopFilesSrcDir = installationFolder + L"dll\\Interop\\"; + colorPickerDir = installationFolder + L"modules\\ColorPicker\\"; + powerOCRDir = installationFolder + L"modules\\PowerOCR\\"; + launcherDir = installationFolder + L"modules\\launcher\\"; + fancyZonesDir = installationFolder + L"modules\\FancyZones\\"; + imageResizerDir = installationFolder + L"modules\\ImageResizer\\"; + settingsDir = installationFolder + L"Settings\\"; + awakeDir = installationFolder + L"modules\\Awake\\"; + measureToolDir = installationFolder + L"modules\\MeasureTool\\"; + powerAccentDir = installationFolder + L"modules\\PowerAccent\\"; + + for (auto file : powerToysInteropFiles) + { + std::error_code ec; + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (colorPickerDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (powerOCRDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (launcherDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (fancyZonesDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (imageResizerDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (settingsDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (awakeDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (measureToolDir + file).c_str(), ec); + std::filesystem::create_hard_link((interopFilesSrcDir + file).c_str(), (powerAccentDir + file).c_str(), ec); + + if (ec.value() != S_OK) + { + std::wstring errorMessage{ L"Error creating hard link for: " }; + errorMessage += file; + errorMessage += L", error code: " + std::to_wstring(ec.value()); + Logger::error(errorMessage); + } + } + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +UINT __stdcall DeleteWinAppSDKHardlinksCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + std::wstring installationFolder, settingsDir, powerRenameDir; + + hr = WcaInitialize(hInstall, "DeleteWinAppSDKHardlinksCA"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = getInstallFolder(hInstall, installationFolder); + ExitOnFailure(hr, "Failed to get installation folder"); + + settingsDir = installationFolder + L"Settings\\"; + powerRenameDir = installationFolder + L"modules\\PowerRename\\"; + + try + { + for (auto file : winAppSdkFiles) + { + DeleteFile((settingsDir + file).c_str()); + DeleteFile((powerRenameDir + file).c_str()); + } + } + catch (std::exception e) + { + std::string errorMessage{ "Exception thrown while trying to delete WAS hardlinks: " }; + errorMessage += e.what(); + Logger::error(errorMessage); + + er = ERROR_INSTALL_FAILURE; + } + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +UINT __stdcall DeletePTInteropHardlinksCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + std::wstring installationFolder, interopFilesSrcDir, colorPickerDir, powerOCRDir, launcherDir, fancyZonesDir, + imageResizerDir, settingsDir, awakeDir, measureToolDir, powerAccentDir; + + hr = WcaInitialize(hInstall, "DeletePTInteropHardlinksCA"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = getInstallFolder(hInstall, installationFolder); + ExitOnFailure(hr, "Failed to get installation folder"); + + colorPickerDir = installationFolder + L"modules\\ColorPicker\\"; + powerOCRDir = installationFolder + L"modules\\PowerOCR\\"; + launcherDir = installationFolder + L"modules\\launcher\\"; + fancyZonesDir = installationFolder + L"modules\\FancyZones\\"; + imageResizerDir = installationFolder + L"modules\\ImageResizer\\"; + settingsDir = installationFolder + L"Settings\\"; + awakeDir = installationFolder + L"modules\\Awake\\"; + measureToolDir = installationFolder + L"modules\\MeasureTool\\"; + powerAccentDir = installationFolder + L"modules\\PowerAccent\\"; + + try + { + for (auto file : powerToysInteropFiles) + { + DeleteFile((colorPickerDir + file).c_str()); + DeleteFile((powerOCRDir + file).c_str()); + DeleteFile((launcherDir + file).c_str()); + DeleteFile((fancyZonesDir + file).c_str()); + DeleteFile((imageResizerDir + file).c_str()); + DeleteFile((settingsDir + file).c_str()); + DeleteFile((awakeDir + file).c_str()); + DeleteFile((measureToolDir + file).c_str()); + DeleteFile((powerAccentDir + file).c_str()); + } + } + catch (std::exception e) + { + std::string errorMessage{ "Exception thrown while trying to delete PowerToys Interop and VC Redist hardlinks: " }; + errorMessage += e.what(); + Logger::error(errorMessage); + + er = ERROR_INSTALL_FAILURE; + } + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall) { diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def index 255b64724e..3a36f02f7d 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.def +++ b/installer/PowerToysSetupCustomActions/CustomAction.def @@ -3,6 +3,10 @@ LIBRARY "PowerToysSetupCustomActions" EXPORTS ApplyModulesRegistryChangeSetsCA CreateScheduledTaskCA + CreateWinAppSDKHardlinksCA + DeleteWinAppSDKHardlinksCA + CreatePTInteropHardlinksCA + DeletePTInteropHardlinksCA DetectPrevInstallPathCA RemoveScheduledTasksCA TelemetryLogInstallSuccessCA diff --git a/src/common/interop/PowerToys.Interop.vcxproj b/src/common/interop/PowerToys.Interop.vcxproj index 8e4e47f6a0..e93b0490d3 100644 --- a/src/common/interop/PowerToys.Interop.vcxproj +++ b/src/common/interop/PowerToys.Interop.vcxproj @@ -51,6 +51,9 @@ PowerToys.Interop $(SolutionDir)$(Platform)\$(Configuration)\ + + true + MultiThreadedDebugDLL