From 9731cdee6743d50fa9d9e59191cf42d6d1c70ade Mon Sep 17 00:00:00 2001 From: Mykhailo Pylyp Date: Wed, 28 Jul 2021 14:15:47 +0300 Subject: [PATCH] Revert "[PowerToys Run] Update to net5 (#12434)" (#12543) This reverts commit c651a4b36ef104f978a8df294c90f521a2a69e39. --- .../ci/templates/build-powertoys-steps.yml | 5 +- .../bootstrapper/DotnetInstallation.cpp | 21 +-- .../bootstrapper/DotnetInstallation.h | 4 +- .../bootstrapper/bootstrapper.cpp | 30 +--- installer/PowerToysSetup/Product.wxs | 2 +- installer/PowerToysSetup/publish.cmd | 2 +- ...s.Run.Plugin.UnitConverter.UnitTest.csproj | 4 +- ....PowerToys.Run.Plugin.UnitConverter.csproj | 4 +- ...werToys.Run.Plugin.VSCodeWorkspaces.csproj | 10 +- .../VSCodeHelper/VSCodeInstances.cs | 5 + .../Microsoft.Plugin.Folder.UnitTests.csproj | 2 +- .../Microsoft.Plugin.Folder.csproj | 4 +- .../Microsoft.Plugin.Indexer.csproj | 8 +- .../Microsoft.Plugin.Program.UnitTests.csproj | 2 +- .../Storage/Win32ProgramRepositoryTest.cs | 26 +-- .../Plugins/Microsoft.Plugin.Program/Main.cs | 4 +- .../Microsoft.Plugin.Program.csproj | 9 +- .../Programs/PackageWrapper.cs | 9 +- .../Storage/IProgramRepository.cs | 4 + .../Storage/PackageRepository.cs | 16 +- .../Storage/Win32ProgramRepository.cs | 15 +- .../Microsoft.Plugin.Shell.csproj | 8 +- .../Microsoft.Plugin.Uri.UnitTests.csproj | 2 +- .../Microsoft.Plugin.Uri.csproj | 8 +- .../Components/OpenWindows.cs | 2 +- .../Components/Window.cs | 11 ++ .../Microsoft.Plugin.WindowWalker.csproj | 8 +- ...Toys.Run.Plugin.Calculator.UnitTest.csproj | 2 +- ...oft.PowerToys.Run.Plugin.Calculator.csproj | 4 +- .../Helper/RegistryHelperTest.cs | 14 +- ...rToys.Run.Plugin.Registry.UnitTests.csproj | 2 +- .../Classes/RegistryEntry.cs | 2 +- .../Helper/QueryHelper.cs | 4 +- .../Helper/RegistryHelper.cs | 18 +- .../Helper/ResultHelper.cs | 8 +- .../Helper/ValueHelper.cs | 8 +- ...osoft.PowerToys.Run.Plugin.Registry.csproj | 2 +- ...rosoft.PowerToys.Run.Plugin.Service.csproj | 2 +- ...werToys.Run.Plugin.System.UnitTests.csproj | 2 +- ...crosoft.PowerToys.Run.Plugin.System.csproj | 4 +- .../Helper/ResultHelper.cs | 2 +- .../Helper/UnsupportedSettingsHelper.cs | 2 +- ...owerToys.Run.Plugin.WindowsSettings.csproj | 4 +- .../launcher/PowerLauncher/App.xaml.cs | 2 +- .../Helper/LauncherNotificationActivator.cs | 23 +++ .../Helper/WindowsInteropHelper.cs | 4 +- .../PowerLauncher/PowerLauncher.csproj | 24 +-- .../PowerLauncher/PublicAPIInstance.cs | 5 +- .../Exception/ExceptionFormatter.cs | 2 +- .../Wox.Infrastructure/Image/ImageCache.cs | 18 +- .../Wox.Infrastructure/Image/ImageLoader.cs | 6 +- .../Storage/BinaryStorage`1.cs | 156 ++++++++++++++++++ .../Wox.Infrastructure/Storage/IStorage`1.cs | 22 +++ .../Storage/WoxJsonStorage`1.cs | 4 +- .../Wox.Infrastructure.csproj | 4 +- .../launcher/Wox.Plugin/Wox.Plugin.csproj | 4 +- src/modules/launcher/Wox.Test/Wox.Test.csproj | 2 +- tools/BugReportTool/BugReportTool/Main.cpp | 1 - 58 files changed, 402 insertions(+), 180 deletions(-) create mode 100644 src/modules/launcher/PowerLauncher/Helper/LauncherNotificationActivator.cs create mode 100644 src/modules/launcher/Wox.Infrastructure/Storage/BinaryStorage`1.cs create mode 100644 src/modules/launcher/Wox.Infrastructure/Storage/IStorage`1.cs diff --git a/.pipelines/ci/templates/build-powertoys-steps.yml b/.pipelines/ci/templates/build-powertoys-steps.yml index d9ac06bb70..2b915c4bda 100644 --- a/.pipelines/ci/templates/build-powertoys-steps.yml +++ b/.pipelines/ci/templates/build-powertoys-steps.yml @@ -129,8 +129,7 @@ steps: **\UnitTest-ColorPickerUI.dll **\Microsoft.Interop.Tests.dll !**\obj\** - !**\ref\** - + - task: VSTest@2 displayName: 'XUnit Tests' inputs: @@ -140,7 +139,6 @@ steps: testAssemblyVer2: | **\ImageResizer.Test.dll !**\obj\** - !**\ref\** - task: VSTest@2 displayName: 'NUnit Tests' @@ -157,7 +155,6 @@ steps: **\Wox.Test.dll **\Microsoft.PowerToys.Run.Plugin.System.UnitTests.dll !**\obj\** - !**\ref\** # Native dlls - task: VSTest@2 diff --git a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp b/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp index 3ec00af3b9..7647dc143f 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp +++ b/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.cpp @@ -9,24 +9,20 @@ namespace fs = std::filesystem; namespace updating { - bool dotnet_is_installed(const size_t major, const size_t minor, const size_t requiredMinimalPatch) + constexpr size_t REQUIRED_MINIMAL_PATCH = 15; + + bool dotnet_is_installed() { auto runtimes = exec_and_read_output(LR"(dotnet --list-runtimes)"); if (!runtimes) { return false; } - std::array regexBuffer; - sprintf_s(regexBuffer.data(), - regexBuffer.size(), - R"(Microsoft\.WindowsDesktop\.App\s%zu\.%zu\.(\d+))", - major, - minor); - std::regex dotnetRegex{ regexBuffer.data() }; + 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), dotnetRegex }; it != rexit{}; ++it) + for (auto it = rexit{ begin(*runtimes), end(*runtimes), dotnet3_1_x }; it != rexit{}; ++it) { if (!it->ready() || it->size() < 2) { @@ -44,15 +40,16 @@ namespace updating latestPatchInstalled = std::max(patch, latestPatchInstalled); } } - return latestPatchInstalled >= requiredMinimalPatch; + return latestPatchInstalled >= REQUIRED_MINIMAL_PATCH; } - std::optional download_dotnet(const wchar_t* dotnetDesktopDownloadLink) + std::optional download_dotnet() { + const wchar_t DOTNET_DESKTOP_DOWNLOAD_LINK[] = L"https://download.visualstudio.microsoft.com/download/pr/d30352fe-d4f3-4203-91b9-01a3b66a802e/bb416e6573fa278fec92113abefc58b3/windowsdesktop-runtime-3.1.15-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{ dotnetDesktopDownloadLink }; + winrt::Windows::Foundation::Uri download_link{ DOTNET_DESKTOP_DOWNLOAD_LINK }; const size_t max_attempts = 3; bool download_success = false; diff --git a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h b/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h index 3d6edc845f..67ff6ad3b9 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h +++ b/installer/PowerToysBootstrapper/bootstrapper/DotnetInstallation.h @@ -6,7 +6,7 @@ namespace fs = std::filesystem; namespace updating { - bool dotnet_is_installed(const size_t major, const size_t minor, const size_t requiredMinimalPatch); - std::optional download_dotnet(const wchar_t* dotnetDesktopDownloadLink); + 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/bootstrapper.cpp b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp index 77e9f71892..571777adbf 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp +++ b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp @@ -407,39 +407,25 @@ int Bootstrapper(HINSTANCE hInstance) { if (installDotnet) { - auto dotnet3Info = std::make_tuple(VersionHelper{ 3, 1, 15 }, - L"https://download.visualstudio.microsoft.com/download/pr/d30352fe-d4f3-4203-91b9-01a3b66a802e/bb416e6573fa278fec92113abefc58b3/windowsdesktop-runtime-3.1.15-win-x64.exe"); - auto dotnet5Info = std::make_tuple(VersionHelper{ 5, 0, 7 }, - L"https://download.visualstudio.microsoft.com/download/pr/2b83d30e-5c86-4d37-a1a6-582e22ac07b2/c7b1b7e21761bbfb7b9951f5b258806e/windowsdesktop-runtime-5.0.7-win-x64.exe"); - - const std::array dotnetsToInstall = { std::move(dotnet3Info), std::move(dotnet5Info) }; - - for (const auto& [ver, downloadLink] : dotnetsToInstall) + spdlog::debug("Detecting if dotnet is installed"); + const bool dotnetInstalled = updating::dotnet_is_installed(); + spdlog::debug("Dotnet is already installed: {}", dotnetInstalled); + if (!dotnetInstalled) { - const auto& [major, minor, minimalRequiredPatch] = ver; - spdlog::debug("Detecting if dotnet {} is installed", ver.toString()); - const bool dotnetInstalled = updating::dotnet_is_installed(major, minor, minimalRequiredPatch); - - if (dotnetInstalled) - { - spdlog::debug("Dotnet {} is already installed: {}", ver.toString(), dotnetInstalled); - continue; - } - bool installedSuccessfully = false; - if (const auto dotnetInstallerPath = updating::download_dotnet(downloadLink)) + if (const auto dotnet_installer_path = updating::download_dotnet()) { // Dotnet installer has its own progress bar CloseProgressBarDialog(); - installedSuccessfully = updating::install_dotnet(*dotnetInstallerPath, g_Silent); + installedSuccessfully = updating::install_dotnet(*dotnet_installer_path, g_Silent); if (!installedSuccessfully) { - spdlog::error("Couldn't install dotnet {}", ver.toString()); + spdlog::error("Couldn't install dotnet"); } } else { - spdlog::error("Couldn't download dotnet {}", ver.toString()); + spdlog::error("Couldn't download dotnet"); } if (!installedSuccessfully) diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 131ea2eef2..507a629c86 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -1078,7 +1078,7 @@ - + diff --git a/installer/PowerToysSetup/publish.cmd b/installer/PowerToysSetup/publish.cmd index 20f2012f4a..6f916c9fae 100644 --- a/installer/PowerToysSetup/publish.cmd +++ b/installer/PowerToysSetup/publish.cmd @@ -50,7 +50,7 @@ echo ^ >> !launcherPublishProfile! echo ^FileSystem^ >> !launcherPublishProfile! echo ^Release^ >> !launcherPublishProfile! echo ^x64^ >> !launcherPublishProfile! -echo ^net5.0-windows10.0.18362.0^ >> !launcherPublishProfile! +echo ^netcoreapp3.1^ >> !launcherPublishProfile! echo ^..\..\..\..\x64\Release\modules\launcher^ >> !launcherPublishProfile! echo ^win-x64^ >> !launcherPublishProfile! echo ^false^ >> !launcherPublishProfile! diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj index 67601feca3..d30c233c44 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj @@ -1,7 +1,7 @@ - + - net5.0-windows + netcoreapp3.1 false diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj index e4adfa975b..fe32784f51 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} Properties Community.PowerToys.Run.Plugin.UnitConverter diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj index 329651c4c9..ed2b977245 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows10.0.18362 + netcoreapp3.1 {4D971245-7A70-41D5-BAA0-DDB5684CAF51} Properties Community.PowerToys.Run.Plugin.VSCodeWorkspaces @@ -56,6 +56,12 @@ + + + C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0\Windows.Foundation.UniversalApiContract.winmd + + + Resources.resx diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/VSCodeHelper/VSCodeInstances.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/VSCodeHelper/VSCodeInstances.cs index b2c5177fba..598089d2cd 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/VSCodeHelper/VSCodeInstances.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/VSCodeHelper/VSCodeInstances.cs @@ -5,7 +5,12 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Reflection; +using System.Windows; +using System.Windows.Interop; +using System.Windows.Media; using System.Windows.Media.Imaging; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj index c6ad628fdd..613d6a9f66 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj @@ -1,7 +1,7 @@ - net5.0-windows + netcoreapp3.1 false x64 diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj index 0187658370..46877d7a23 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} Properties Microsoft.Plugin.Folder diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj index bac4c94aff..fb8aa6bf0f 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {F8B870EB-D5F5-45BA-9CF7-A5C459818820} Properties Microsoft.Plugin.Indexer @@ -53,10 +53,10 @@ - + false - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj index 1163501145..4cf3c81355 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj @@ -1,7 +1,7 @@  - net5.0-windows10.0.18362 + netcoreapp3.1 false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs index a885cbc897..c05955fd5a 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs @@ -43,7 +43,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32RepositoryMustNotStoreDuplicatesWhileAddingItemsWithSameHashCode(string name, string exename, string fullPath, string description1, string description2) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); Win32Program item1 = new Win32Program { @@ -77,7 +77,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppCreatedForApprefAppsWhenCreatedEventIsRaised(string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Created, "directory", path); // Act @@ -92,7 +92,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppDeletedForApprefAppsWhenDeletedEventIsRaised(string directory, string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path); string fullPath = directory + "\\" + path; @@ -110,7 +110,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppRenamedForApprefAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); RenamedEventArgs e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath); string oldFullPath = directory + "\\" + oldpath; @@ -133,7 +133,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppCreatedForExeAppsWhenCreatedEventIsRaised(string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Created, "directory", path); // FileVersionInfo must be mocked for exe applications @@ -153,7 +153,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppDeletedForExeAppsWhenDeletedEventIsRaised(string directory, string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path); // FileVersionInfo must be mocked for exe applications @@ -176,7 +176,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppRenamedForExeAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); RenamedEventArgs e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath); string oldFullPath = directory + "\\" + oldpath; @@ -206,7 +206,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage // We are handing internet shortcut apps using the Changed event instead // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Created, "directory", path); // File.ReadAllLines must be mocked for url applications @@ -229,7 +229,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage // We are handing internet shortcut apps using the Changed event instead // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Changed, "directory", path); // FileVersionInfo must be mocked for exe applications @@ -253,7 +253,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppDeletedForUrlAppsWhenDeletedEventIsRaised(string directory, string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path); // File.ReadAllLines must be mocked for url applications @@ -276,7 +276,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppRenamedForUrlAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); RenamedEventArgs e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, newpath, oldpath); // File.ReadAllLines must be mocked for url applications @@ -304,7 +304,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppDeletedForLnkAppsWhenDeletedEventIsRaised(string directory, string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Deleted, directory, path); // ShellLinkHelper must be mocked for lnk applications @@ -334,7 +334,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public void Win32ProgramRepositoryMustCallOnAppRenamedForLnkAppsWhenRenamedEventIsRaised(string directory, string oldpath, string path) { // Arrange - Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); + Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage>("Win32"), _settings, _pathsToWatch); RenamedEventArgs e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, path, oldpath); string oldFullPath = directory + "\\" + oldpath; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs index c9c5a238c1..4d078cb0af 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs @@ -39,7 +39,7 @@ namespace Microsoft.Plugin.Program private static PluginInitContext _context; private readonly PluginJsonStorage _settingsStorage; private bool _disposed; - private PackageRepository _packageRepository = new PackageRepository(new PackageCatalogWrapper()); + private PackageRepository _packageRepository = new PackageRepository(new PackageCatalogWrapper(), new BinaryStorage>("UWP")); private static Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper; private static Win32ProgramRepository _win32ProgramRepository; @@ -52,7 +52,7 @@ namespace Microsoft.Plugin.Program _win32ProgramRepositoryHelper = new Win32ProgramFileSystemWatchers(); // Initialize the Win32ProgramRepository with the settings object - _win32ProgramRepository = new Win32ProgramRepository(_win32ProgramRepositoryHelper.FileSystemWatchers.Cast().ToList(), Settings, _win32ProgramRepositoryHelper.PathsToWatch); + _win32ProgramRepository = new Win32ProgramRepository(_win32ProgramRepositoryHelper.FileSystemWatchers.Cast().ToList(), new BinaryStorage>("Win32"), Settings, _win32ProgramRepositoryHelper.PathsToWatch); } public void Save() diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj index 80371a0442..e6a6440285 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows10.0.18362.0 + netcoreapp3.1 {FDB3555B-58EF-4AE6-B5F1-904719637AB4} Properties Microsoft.Plugin.Program @@ -57,10 +57,10 @@ - + false - + false @@ -71,6 +71,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/PackageWrapper.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/PackageWrapper.cs index 30efe6dfc8..afe3c0e50c 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/PackageWrapper.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/PackageWrapper.cs @@ -39,6 +39,9 @@ namespace Microsoft.Plugin.Program.Programs InstalledLocation = installedLocation; } + private static readonly Lazy IsPackageDotInstallationPathAvailable = new Lazy(() => + ApiInformation.IsPropertyPresent(typeof(Package).FullName, nameof(Package.InstalledPath))); + public static PackageWrapper GetWrapperFromPackage(Package package) { if (package == null) @@ -49,7 +52,7 @@ namespace Microsoft.Plugin.Program.Programs string path; try { - path = package.InstalledLocation.Path; + path = IsPackageDotInstallationPathAvailable.Value ? GetInstalledPath(package) : package.InstalledLocation.Path; } catch (Exception e) when (e is ArgumentException || e is FileNotFoundException || e is DirectoryNotFoundException) { @@ -71,5 +74,9 @@ namespace Microsoft.Plugin.Program.Programs package.IsDevelopmentMode, path); } + + // This is a separate method so the reference to .InstalledPath won't be loaded in API versions which do not support this API (e.g. older then Build 19041) + private static string GetInstalledPath(Package package) + => package.InstalledPath; } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/IProgramRepository.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/IProgramRepository.cs index afdeb27264..5d65b03b66 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/IProgramRepository.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/IProgramRepository.cs @@ -7,5 +7,9 @@ namespace Microsoft.Plugin.Program.Storage internal interface IProgramRepository { void IndexPrograms(); + + void Load(); + + void Save(); } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/PackageRepository.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/PackageRepository.cs index 2f268a17ca..1446987df1 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/PackageRepository.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/PackageRepository.cs @@ -19,10 +19,13 @@ namespace Microsoft.Plugin.Program.Storage /// internal class PackageRepository : ListRepository, IProgramRepository { + private IStorage> _storage; + private IPackageCatalog _packageCatalog; - public PackageRepository(IPackageCatalog packageCatalog) + public PackageRepository(IPackageCatalog packageCatalog, IStorage> storage) { + _storage = storage ?? throw new ArgumentNullException(nameof(storage), "StorageRepository requires an initialized storage interface"); _packageCatalog = packageCatalog ?? throw new ArgumentNullException(nameof(packageCatalog), "PackageRepository expects an interface to be able to subscribe to package events"); _packageCatalog.PackageInstalling += OnPackageInstalling; _packageCatalog.PackageUninstalling += OnPackageUninstalling; @@ -81,5 +84,16 @@ namespace Microsoft.Plugin.Program.Storage Log.Info($"Indexed {applications.Length} packaged applications", GetType()); SetList(applications); } + + public void Save() + { + _storage.Save(Items); + } + + public void Load() + { + var items = _storage.TryLoad(Array.Empty()); + SetList(items); + } } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs index 31194a8d65..691a449a71 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs @@ -24,6 +24,7 @@ namespace Microsoft.Plugin.Program.Storage private const string LnkExtension = ".lnk"; private const string UrlExtension = ".url"; + private IStorage> _storage; private ProgramPluginSettings _settings; private IList _fileSystemWatcherHelpers; private string[] _pathsToWatch; @@ -32,9 +33,10 @@ namespace Microsoft.Plugin.Program.Storage private static ConcurrentQueue commonEventHandlingQueue = new ConcurrentQueue(); - public Win32ProgramRepository(IList fileSystemWatcherHelpers, ProgramPluginSettings settings, string[] pathsToWatch) + public Win32ProgramRepository(IList fileSystemWatcherHelpers, IStorage> storage, ProgramPluginSettings settings, string[] pathsToWatch) { _fileSystemWatcherHelpers = fileSystemWatcherHelpers; + _storage = storage ?? throw new ArgumentNullException(nameof(storage), "Win32ProgramRepository requires an initialized storage interface"); _settings = settings ?? throw new ArgumentNullException(nameof(settings), "Win32ProgramRepository requires an initialized settings object"); _pathsToWatch = pathsToWatch; _numberOfPathsToWatch = pathsToWatch.Length; @@ -244,5 +246,16 @@ namespace Microsoft.Plugin.Program.Storage Log.Info($"Indexed {applications.Count} win32 applications", GetType()); SetList(applications); } + + public void Save() + { + _storage.Save(Items); + } + + public void Load() + { + var items = _storage.TryLoad(Array.Empty()); + SetList(items); + } } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj index fa1bda7648..f3f37b892b 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} Properties Microsoft.Plugin.Shell @@ -48,10 +48,10 @@ - + false - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj index 0349c8cc8e..3f4ee12d6e 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj @@ -1,7 +1,7 @@  - net5.0-windows + netcoreapp3.1 false x64 diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj index c092a1ffac..dfed382044 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {03276a39-d4e9-417c-8ffd-200b0ee5e871} Properties Microsoft.Plugin.Uri @@ -58,10 +58,10 @@ - + false - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs index c4198cf68b..fccf71c5d9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs @@ -84,7 +84,7 @@ namespace Microsoft.Plugin.WindowWalker.Components { Window newWindow = new Window(hwnd); - if (newWindow.IsWindow && newWindow.Visible && + if (newWindow.IsWindow && newWindow.Visible && newWindow.IsOwner && (!newWindow.IsToolWindow || newWindow.IsAppWindow) && !newWindow.TaskListDeleted && newWindow.ClassName != "Windows.UI.Core.CoreWindow") { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs index 3630302a52..7e28b738fc 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs @@ -210,6 +210,17 @@ namespace Microsoft.Plugin.WindowWalker.Components } } + /// + /// Gets a value indicating whether determines whether the specified windows is the owner + /// + public bool IsOwner + { + get + { + return NativeMethods.GetWindow(Hwnd, NativeMethods.GetWindowCmd.GW_OWNER) != null; + } + } + /// /// Gets a value indicating whether returns true if the window is minimized /// diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj index 5950806006..0d9903857b 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {74F1B9ED-F59C-4FE7-B473-7B453E30837E} Properties Microsoft.Plugin.WindowWalker @@ -60,10 +60,10 @@ - + false - + false diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj index 0f98a232db..bdffa1cb1d 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj @@ -1,7 +1,7 @@ - net5.0-windows + netcoreapp3.1 false x64 diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj index 1afa4aba61..f38db5ca5b 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {59BD9891-3837-438A-958D-ADC7F91F6F7E} Properties Microsoft.PowerToys.Run.Plugin.Calculator diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Helper/RegistryHelperTest.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Helper/RegistryHelperTest.cs index c56390f297..8855d3e23e 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Helper/RegistryHelperTest.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Helper/RegistryHelperTest.cs @@ -22,8 +22,8 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.UnitTest.Helper public void GetRegistryBaseKeyTestOnlyOneBaseKey(string query, string expectedBaseKey) { var (baseKeyList, _) = RegistryHelper.GetRegistryBaseKey(query); - Assert.IsTrue(baseKeyList != null && baseKeyList.Count() == 1); - Assert.AreEqual(expectedBaseKey, baseKeyList?.FirstOrDefault()?.Name ?? string.Empty); + Assert.IsTrue(baseKeyList.Count() == 1); + Assert.AreEqual(expectedBaseKey, baseKeyList.FirstOrDefault().Name); } [TestMethod] @@ -31,12 +31,12 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.UnitTest.Helper { var (baseKeyList, _) = RegistryHelper.GetRegistryBaseKey("HKC\\Control Panel\\Accessibility"); /* #no-spell-check-line */ - Assert.IsTrue(baseKeyList != null && baseKeyList.Count() > 1); + Assert.IsTrue(baseKeyList.Count() > 1); - var list = baseKeyList?.Select(found => found.Name); - Assert.IsTrue(list?.Contains("HKEY_CLASSES_ROOT")); - Assert.IsTrue(list?.Contains("HKEY_CURRENT_CONFIG")); - Assert.IsTrue(list?.Contains("HKEY_CURRENT_USER")); + var list = baseKeyList.Select(found => found.Name); + Assert.IsTrue(list.Contains("HKEY_CLASSES_ROOT")); + Assert.IsTrue(list.Contains("HKEY_CURRENT_CONFIG")); + Assert.IsTrue(list.Contains("HKEY_CURRENT_USER")); } [TestMethod] diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj index c328e76048..4122d0b1e0 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj @@ -1,7 +1,7 @@  - net5.0-windows + netcoreapp3.1 x64 en-US 8.0 diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Classes/RegistryEntry.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Classes/RegistryEntry.cs index f24b8b6f32..691f1dd3b5 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Classes/RegistryEntry.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Classes/RegistryEntry.cs @@ -65,7 +65,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Classes /// The for this entry. /// The value name of the current selected registry value. /// The value of the current selected registry value. - internal RegistryEntry(RegistryKey key, string valueName, object? value) + internal RegistryEntry(RegistryKey key, string valueName, object value) { KeyPath = key.Name; Key = key; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/QueryHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/QueryHelper.cs index 06664d5b5f..3e37f3b193 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/QueryHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/QueryHelper.cs @@ -50,8 +50,8 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper var querySplit = query.Split(QuerySplitCharacter); - queryKey = querySplit.FirstOrDefault() ?? string.Empty; - queryValueName = querySplit.LastOrDefault() ?? string.Empty; + queryKey = querySplit.FirstOrDefault(); + queryValueName = querySplit.LastOrDefault(); return true; } diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/RegistryHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/RegistryHelper.cs index aa659c0316..90cf1965cd 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/RegistryHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/RegistryHelper.cs @@ -51,8 +51,9 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper return (null, string.Empty); } - var baseKey = query.Split('\\').FirstOrDefault() ?? string.Empty; + var baseKey = query.Split('\\').FirstOrDefault(); var subKey = query.Replace(baseKey, string.Empty, StringComparison.InvariantCultureIgnoreCase).TrimStart('\\'); + var baseKeyResult = _baseKeys .Where(found => found.Key.StartsWith(baseKey, StringComparison.InvariantCultureIgnoreCase)) .Select(found => found.Value) @@ -99,7 +100,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper do { - result = FindSubKey(subKey, subKeysNames.ElementAtOrDefault(index) ?? string.Empty); + result = FindSubKey(subKey, subKeysNames.ElementAtOrDefault(index)); if (result.Count == 0) { @@ -167,22 +168,13 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper if (string.Equals(subKey, searchSubKey, StringComparison.InvariantCultureIgnoreCase)) { - var key = parentKey.OpenSubKey(subKey, RegistryKeyPermissionCheck.ReadSubTree); - if (key != null) - { - list.Add(new RegistryEntry(key)); - } - + list.Add(new RegistryEntry(parentKey.OpenSubKey(subKey, RegistryKeyPermissionCheck.ReadSubTree))); return list; } try { - var key = parentKey.OpenSubKey(subKey, RegistryKeyPermissionCheck.ReadSubTree); - if (key != null) - { - list.Add(new RegistryEntry(key)); - } + list.Add(new RegistryEntry(parentKey.OpenSubKey(subKey, RegistryKeyPermissionCheck.ReadSubTree))); } catch (Exception exception) { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ResultHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ResultHelper.cs index 3b7ca0bcd9..b6f1b050f8 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ResultHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ResultHelper.cs @@ -82,7 +82,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper return new List(0); } - ICollection> valueList = new List>(key.ValueCount); + ICollection> valueList = new List>(key.ValueCount); var resultList = new List(); @@ -116,7 +116,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper if (!string.IsNullOrEmpty(searchValue)) { var filteredValueName = valueList.Where(found => found.Key.Contains(searchValue, StringComparison.InvariantCultureIgnoreCase)); - var filteredValueList = valueList.Where(found => found.Value?.ToString()?.Contains(searchValue, StringComparison.InvariantCultureIgnoreCase) ?? false); + var filteredValueList = valueList.Where(found => found.Value.ToString()?.Contains(searchValue, StringComparison.InvariantCultureIgnoreCase) ?? false); valueList = filteredValueName.Concat(filteredValueList).Distinct().ToList(); } @@ -196,7 +196,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper /// The registry key for the tool-tip /// The value name and value of the registry value /// A tool-tip text - private static string GetToolTipTextForRegistryValue(RegistryKey key, KeyValuePair valueEntry) + private static string GetToolTipTextForRegistryValue(RegistryKey key, KeyValuePair valueEntry) { return $"{Resources.KeyName}\t{key.Name}{Environment.NewLine}" + $"{Resources.Name}\t{valueEntry.Key}{Environment.NewLine}" @@ -210,7 +210,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper /// The registry key for the sub-title /// The value name and value of the registry value /// A sub-title text - private static string GetSubTileForRegistryValue(RegistryKey key, KeyValuePair valueEntry) + private static string GetSubTileForRegistryValue(RegistryKey key, KeyValuePair valueEntry) { return $"{Resources.Type} {ValueHelper.GetType(key, valueEntry.Key)}" + $" - {Resources.Value} {ValueHelper.GetValue(key, valueEntry.Key, 50)}"; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ValueHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ValueHelper.cs index 42116a3bf0..d3bf3a9790 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ValueHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Helper/ValueHelper.cs @@ -25,13 +25,11 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper { var unformattedValue = key.GetValue(valueName); - var unformattedValueInt = unformattedValue != null ? (uint)(int)unformattedValue : 0; - var unformattedValueLong = unformattedValue != null ? (ulong)(long)unformattedValue : 0; var valueData = key.GetValueKind(valueName) switch { - RegistryValueKind.DWord => $"0x{unformattedValue:X8} ({unformattedValueInt})", - RegistryValueKind.QWord => $"0x{unformattedValue:X16} ({unformattedValueLong})", - RegistryValueKind.Binary => (unformattedValue as byte[] ?? Array.Empty()).Aggregate(string.Empty, (current, singleByte) => $"{current} {singleByte:X2}"), + RegistryValueKind.DWord => $"0x{unformattedValue:X8} ({(uint)(int)unformattedValue})", + RegistryValueKind.QWord => $"0x{unformattedValue:X16} ({(ulong)(long)unformattedValue})", + RegistryValueKind.Binary => (unformattedValue as byte[]).Aggregate(string.Empty, (current, singleByte) => $"{current} {singleByte:X2}"), _ => $"{unformattedValue}", }; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj index 58f436750b..12a5ec6470 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj @@ -1,7 +1,7 @@  - net5.0-windows + netcoreapp3.1 Microsoft.PowerToys.Run.Plugin.Registry Microsoft.PowerToys.Run.Plugin.Registry $(Version).0 diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj index 27641552e2..966ee3723d 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj @@ -3,7 +3,7 @@ - net5.0-windows + netcoreapp3.1 Microsoft.PowerToys.Run.Plugin.Service Microsoft.PowerToys.Run.Plugin.Service $(Version).0 diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj index 73f746ba2f..de7ed9270b 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj @@ -1,7 +1,7 @@  - net5.0-windows + netcoreapp3.1 false x64 diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj index 4115690563..fbd094c28c 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj @@ -1,9 +1,9 @@ - + Library - net5.0-windows + netcoreapp3.1 Properties Microsoft.PowerToys.Run.Plugin.System Microsoft.PowerToys.Run.Plugin.System diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/ResultHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/ResultHelper.cs index 0a8437c8fa..fbea9bab1b 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/ResultHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/ResultHelper.cs @@ -103,7 +103,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper if (command.Contains(' ')) { var commandSplit = command.Split(' '); - var file = commandSplit.FirstOrDefault() ?? string.Empty; + var file = commandSplit.FirstOrDefault(); var arguments = command[file.Length..].TrimStart(); processStartInfo = new ProcessStartInfo(file, arguments) diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs index bc35594c8d..d455067f46 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs @@ -65,7 +65,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper /// A registry value or on error. private static uint GetNumericRegistryValue(in string registryKey, in string valueName) { - object? registryValueData; + object registryValueData; try { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj index 3a1e482b94..4b7cf12b22 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {5043CECE-E6A7-4867-9CBE-02D27D83747A} Properties Microsoft.PowerToys.Run.Plugin.WindowsSettings diff --git a/src/modules/launcher/PowerLauncher/App.xaml.cs b/src/modules/launcher/PowerLauncher/App.xaml.cs index f576875cdd..2fb7276a92 100644 --- a/src/modules/launcher/PowerLauncher/App.xaml.cs +++ b/src/modules/launcher/PowerLauncher/App.xaml.cs @@ -43,7 +43,7 @@ namespace PowerLauncher [STAThread] public static void Main() { - Log.Info($"Starting PowerToys Run with PID={Environment.ProcessId}", typeof(App)); + Log.Info($"Starting PowerToys Run with PID={Process.GetCurrentProcess().Id}", typeof(App)); int powerToysPid = GetPowerToysPId(); if (powerToysPid != 0) { diff --git a/src/modules/launcher/PowerLauncher/Helper/LauncherNotificationActivator.cs b/src/modules/launcher/PowerLauncher/Helper/LauncherNotificationActivator.cs new file mode 100644 index 0000000000..54036880bd --- /dev/null +++ b/src/modules/launcher/PowerLauncher/Helper/LauncherNotificationActivator.cs @@ -0,0 +1,23 @@ +// 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. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Toolkit.Uwp.Notifications; + +namespace PowerLauncher.Helper +{ + [ClassInterface(ClassInterfaceType.None)] +#pragma warning disable CS0618 // Type or member is obsolete + [ComSourceInterfaces(typeof(INotificationActivationCallback))] +#pragma warning restore CS0618 // Type or member is obsolete + [Guid("DD5CACDA-7C2E-4997-A62A-04A597B58F76")] + [ComVisible(true)] + public class LauncherNotificationActivator : NotificationActivator + { + public override void OnActivated(string invokedArgs, NotificationUserInput userInput, string appUserModelId) + { + } + } +} diff --git a/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs b/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs index 7a68cbd771..2c2e756ea6 100644 --- a/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs +++ b/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs @@ -114,7 +114,7 @@ namespace PowerLauncher.Helper // get current active window IntPtr hWnd = NativeMethods.GetForegroundWindow(); - if (!hWnd.Equals(IntPtr.Zero)) + if (hWnd != null && !hWnd.Equals(IntPtr.Zero)) { // if current active window is NOT desktop or shell if (!(hWnd.Equals(HWND_DESKTOP) || hWnd.Equals(HWND_SHELL))) @@ -142,7 +142,7 @@ namespace PowerLauncher.Helper { IntPtr hWndDesktop = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null); hWndDesktop = NativeMethods.FindWindowEx(hWndDesktop, IntPtr.Zero, "SysListView32", "FolderView"); - if (!hWndDesktop.Equals(IntPtr.Zero)) + if (hWndDesktop != null && !hWndDesktop.Equals(IntPtr.Zero)) { return false; } diff --git a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj index 22b8a4b191..bc7c6ea37f 100644 --- a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj +++ b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj @@ -1,8 +1,8 @@ - + WinExe - net5.0-windows10.0.18362.0 + netcoreapp3.1 true true PowerLauncher.App @@ -89,31 +89,31 @@ - + NU1701 - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - + + + NU1701 - + diff --git a/src/modules/launcher/PowerLauncher/PublicAPIInstance.cs b/src/modules/launcher/PowerLauncher/PublicAPIInstance.cs index 8dd21b057d..52f5f2b1f6 100644 --- a/src/modules/launcher/PowerLauncher/PublicAPIInstance.cs +++ b/src/modules/launcher/PowerLauncher/PublicAPIInstance.cs @@ -35,6 +35,9 @@ namespace Wox _themeManager = themeManager ?? throw new ArgumentNullException(nameof(themeManager)); _themeManager.ThemeChanged += OnThemeChanged; WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); + + DesktopNotificationManagerCompat.RegisterActivator(); + DesktopNotificationManagerCompat.RegisterAumidAndComServer("PowerToysRun"); } public void ChangeQuery(string query, bool requery = false) @@ -93,7 +96,7 @@ namespace Wox Application.Current.Dispatcher.Invoke(() => { var toast = new ToastNotification(builder.GetToastContent().GetXml()); - ToastNotificationManagerCompat.CreateToastNotifier().Show(toast); + DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast); }); } diff --git a/src/modules/launcher/Wox.Infrastructure/Exception/ExceptionFormatter.cs b/src/modules/launcher/Wox.Infrastructure/Exception/ExceptionFormatter.cs index b42e105323..85302cd4b6 100644 --- a/src/modules/launcher/Wox.Infrastructure/Exception/ExceptionFormatter.cs +++ b/src/modules/launcher/Wox.Infrastructure/Exception/ExceptionFormatter.cs @@ -88,7 +88,7 @@ namespace Wox.Infrastructure.Exception sb.AppendLine(); sb.AppendLine("## Assemblies - " + AppDomain.CurrentDomain.FriendlyName); sb.AppendLine(); - foreach (var ass in AppDomain.CurrentDomain.GetAssemblies()) + foreach (var ass in AppDomain.CurrentDomain.GetAssemblies().OrderBy(o => o.GlobalAssemblyCache ? 50 : 0)) { sb.Append("* "); sb.Append(ass.FullName); diff --git a/src/modules/launcher/Wox.Infrastructure/Image/ImageCache.cs b/src/modules/launcher/Wox.Infrastructure/Image/ImageCache.cs index 64991110fa..69d064207b 100644 --- a/src/modules/launcher/Wox.Infrastructure/Image/ImageCache.cs +++ b/src/modules/launcher/Wox.Infrastructure/Image/ImageCache.cs @@ -7,7 +7,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Windows.Media; -using Wox.Infrastructure.Storage; using Wox.Plugin; namespace Wox.Infrastructure.Image @@ -20,16 +19,8 @@ namespace Wox.Infrastructure.Image private readonly ConcurrentDictionary _data = new ConcurrentDictionary(); - [NonSerialized] - private readonly WoxJsonStorage> _usageStorage; - public ConcurrentDictionary Usage { get; private set; } = new ConcurrentDictionary(); - public ImageCache() - { - _usageStorage = new WoxJsonStorage>("ImageUsageCache"); - } - public ImageSource this[string path] { get @@ -96,14 +87,9 @@ namespace Wox.Infrastructure.Image return new Dictionary(Usage); } - public void Initialize() + public void SetUsageAsDictionary(Dictionary usage) { - Usage = _usageStorage.Load(); - } - - public void Save() - { - _usageStorage.Save(); + Usage = new ConcurrentDictionary(usage); } } } diff --git a/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs b/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs index 9321545bd8..ccb9d210d6 100644 --- a/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs +++ b/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs @@ -29,6 +29,7 @@ namespace Wox.Infrastructure.Image private static readonly ImageCache ImageCache = new ImageCache(); private static readonly ConcurrentDictionary GuidToKey = new ConcurrentDictionary(); + private static BinaryStorage> _storage; private static IImageHashGenerator _hashGenerator; public static string ErrorIconPath { get; set; } @@ -48,8 +49,9 @@ namespace Wox.Infrastructure.Image public static void Initialize(Theme theme) { + _storage = new BinaryStorage>("Image"); _hashGenerator = new ImageHashGenerator(); - ImageCache.Initialize(); + ImageCache.SetUsageAsDictionary(_storage.TryLoad(new Dictionary())); foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon, Constant.LightThemedDefaultIcon, Constant.LightThemedErrorIcon }) { @@ -76,7 +78,7 @@ namespace Wox.Infrastructure.Image public static void Save() { ImageCache.Cleanup(); - ImageCache.Save(); + _storage.Save(ImageCache.GetUsageAsDictionary()); } // Todo : Update it with icons specific to each theme. diff --git a/src/modules/launcher/Wox.Infrastructure/Storage/BinaryStorage`1.cs b/src/modules/launcher/Wox.Infrastructure/Storage/BinaryStorage`1.cs new file mode 100644 index 0000000000..c6abbcdea6 --- /dev/null +++ b/src/modules/launcher/Wox.Infrastructure/Storage/BinaryStorage`1.cs @@ -0,0 +1,156 @@ +// 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. + +using System; +using System.IO; +using System.IO.Abstractions; +using System.Reflection; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters; +using System.Runtime.Serialization.Formatters.Binary; +using Wox.Plugin; +using Wox.Plugin.Logger; + +namespace Wox.Infrastructure.Storage +{ + /// + /// Storage object using binary data + /// Normally, it has better performance, but not readable + /// + public class BinaryStorage : IStorage + { + private readonly IFileSystem _fileSystem; + + // This storage helper returns whether or not to delete the binary storage items + private const int _binaryStorage = 0; + private StoragePowerToysVersionInfo _storageHelper; + + public BinaryStorage(string filename) + : this(filename, new FileSystem()) + { + } + + public BinaryStorage(string filename, IFileSystem fileSystem) + { + _fileSystem = fileSystem; + + const string directoryName = "Cache"; + var path = _fileSystem.Path; + var directoryPath = path.Combine(Constant.DataDirectory, directoryName); + Helper.ValidateDirectory(directoryPath); + + const string fileSuffix = ".cache"; + FilePath = path.Combine(directoryPath, $"{filename}{fileSuffix}"); + } + + public string FilePath { get; } + + public T TryLoad(T defaultData) + { + _storageHelper = new StoragePowerToysVersionInfo(FilePath, _binaryStorage); + + // Depending on the version number of the previously installed PT Run, delete the cache if it is found to be incompatible + if (_storageHelper.ClearCache) + { + if (_fileSystem.File.Exists(FilePath)) + { + _fileSystem.File.Delete(FilePath); + + Log.Info($"Deleting cached data at <{FilePath}>", GetType()); + } + } + + if (_fileSystem.File.Exists(FilePath)) + { + if (_fileSystem.FileInfo.FromFileName(FilePath).Length == 0) + { + Log.Error($"Zero length cache file <{FilePath}>", GetType()); + + Save(defaultData); + return defaultData; + } + + using (var stream = _fileSystem.FileStream.Create(FilePath, FileMode.Open)) + { + var d = Deserialize(stream, defaultData); + return d; + } + } + else + { + Log.Info("Cache file not exist, load default data", GetType()); + + Save(defaultData); + return defaultData; + } + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")] + private T Deserialize(Stream stream, T defaultData) + { + // http://stackoverflow.com/questions/2120055/binaryformatter-deserialize-gives-serializationexception + AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; + BinaryFormatter binaryFormatter = new BinaryFormatter + { + AssemblyFormat = FormatterAssemblyStyle.Simple, + }; + + try + { + var t = ((T)binaryFormatter.Deserialize(stream)).NonNull(); + return t; + } + catch (System.Exception e) + { + Log.Exception($"Deserialize error for file <{FilePath}>", e, GetType()); + + return defaultData; + } + finally + { + AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; + } + } + + private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) + { + Assembly ayResult = null; + string sShortAssemblyName = args.Name.Split(',')[0]; + Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (Assembly ayAssembly in ayAssemblies) + { + if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) + { + ayResult = ayAssembly; + break; + } + } + + return ayResult; + } + + public void Save(T data) + { + using (var stream = new FileStream(FilePath, FileMode.Create)) + { + BinaryFormatter binaryFormatter = new BinaryFormatter + { + AssemblyFormat = FormatterAssemblyStyle.Simple, + }; + + try + { + binaryFormatter.Serialize(stream, data); + } + catch (SerializationException e) + { + Log.Exception($"Serialize error for file <{FilePath}>", e, GetType()); + } + } + + _storageHelper.Close(); + Log.Info($"Saving cached data at <{FilePath}>", GetType()); + } + } +} diff --git a/src/modules/launcher/Wox.Infrastructure/Storage/IStorage`1.cs b/src/modules/launcher/Wox.Infrastructure/Storage/IStorage`1.cs new file mode 100644 index 0000000000..ec73368a87 --- /dev/null +++ b/src/modules/launcher/Wox.Infrastructure/Storage/IStorage`1.cs @@ -0,0 +1,22 @@ +// 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. + +namespace Wox.Infrastructure.Storage +{ + public interface IStorage + { + /// + /// Saves the data + /// + /// data to be saved + void Save(T data); + + /// + /// Attempts to load data, otherwise it will return the default provided + /// + /// default data value + /// The loaded data or default + T TryLoad(T defaultData); + } +} diff --git a/src/modules/launcher/Wox.Infrastructure/Storage/WoxJsonStorage`1.cs b/src/modules/launcher/Wox.Infrastructure/Storage/WoxJsonStorage`1.cs index 34e50a756e..8a62c78015 100644 --- a/src/modules/launcher/Wox.Infrastructure/Storage/WoxJsonStorage`1.cs +++ b/src/modules/launcher/Wox.Infrastructure/Storage/WoxJsonStorage`1.cs @@ -13,12 +13,12 @@ namespace Wox.Infrastructure.Storage private static readonly IFileSystem FileSystem = new FileSystem(); private static readonly IPath Path = FileSystem.Path; - public WoxJsonStorage(string fileName = "") + public WoxJsonStorage() { var directoryPath = Path.Combine(Constant.DataDirectory, DirectoryName); Helper.ValidateDirectory(directoryPath); - var filename = fileName != null && fileName.Length != 0 ? fileName : typeof(T).Name; + var filename = typeof(T).Name; FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}"); } } diff --git a/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj b/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj index e75b0a3751..eb3e3f9a34 100644 --- a/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} Library true diff --git a/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj b/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj index a9c3cbde77..6ce7a44086 100644 --- a/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj +++ b/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj @@ -1,8 +1,8 @@ - + - net5.0-windows + netcoreapp3.1 {8451ECDD-2EA4-4966-BB0A-7BBC40138E80} true Library diff --git a/src/modules/launcher/Wox.Test/Wox.Test.csproj b/src/modules/launcher/Wox.Test/Wox.Test.csproj index a8dd47a089..d7817e7541 100644 --- a/src/modules/launcher/Wox.Test/Wox.Test.csproj +++ b/src/modules/launcher/Wox.Test/Wox.Test.csproj @@ -2,7 +2,7 @@ - net5.0-windows10.0.18362 + netcoreapp3.1 {FF742965-9A80-41A5-B042-D6C7D3A21708} Library Properties diff --git a/tools/BugReportTool/BugReportTool/Main.cpp b/tools/BugReportTool/BugReportTool/Main.cpp index 1afa13746b..011f8e6029 100644 --- a/tools/BugReportTool/BugReportTool/Main.cpp +++ b/tools/BugReportTool/BugReportTool/Main.cpp @@ -30,7 +30,6 @@ map> escapeInfo = { vector filesToDelete = { L"PowerToys Run\\Cache", - L"PowerToys Run\\Settings\\ImageUsageCache.json", L"PowerRename\\replace-mru.json", L"PowerRename\\search-mru.json", L"PowerToys Run\\Settings\\UserSelectedRecord.json",