Revert "[PowerToys Run] Update to net5 (#12434)" (#12543)

This reverts commit c651a4b36e.
This commit is contained in:
Mykhailo Pylyp 2021-07-28 14:15:47 +03:00 committed by GitHub
parent 0c02a9acd7
commit 9731cdee67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 402 additions and 180 deletions

View file

@ -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

View file

@ -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<char, 512> 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<fs::path> download_dotnet(const wchar_t* dotnetDesktopDownloadLink)
std::optional<fs::path> 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;

View file

@ -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<fs::path> download_dotnet(const wchar_t* dotnetDesktopDownloadLink);
bool dotnet_is_installed();
std::optional<fs::path> download_dotnet();
bool install_dotnet(fs::path dotnet_download_path, const bool silent);
}

View file

@ -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)

View file

@ -1078,7 +1078,7 @@
<Component Id="launcherInstallComponent" Directory="LauncherInstallFolder" Guid="5E688DB4-C522-4268-BA54-ED1CDFFE9DB6">
<File Source="$(var.BinX64Dir)modules\Launcher\Microsoft.Launcher.dll" />
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll?>
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
<File Id="File_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\$(var.File)" />
<?endforeach?>
<File Source="$(var.BinX64Dir)Settings\Microsoft.PowerToys.Settings.UI.Lib.dll" />

View file

@ -50,7 +50,7 @@ echo ^<PropertyGroup^> >> !launcherPublishProfile!
echo ^<PublishProtocol^>FileSystem^</PublishProtocol^> >> !launcherPublishProfile!
echo ^<Configuration^>Release^</Configuration^> >> !launcherPublishProfile!
echo ^<Platform^>x64^</Platform^> >> !launcherPublishProfile!
echo ^<TargetFramework^>net5.0-windows10.0.18362.0^</TargetFramework^> >> !launcherPublishProfile!
echo ^<TargetFramework^>netcoreapp3.1^</TargetFramework^> >> !launcherPublishProfile!
echo ^<PublishDir^>..\..\..\..\x64\Release\modules\launcher^</PublishDir^> >> !launcherPublishProfile!
echo ^<RuntimeIdentifier^>win-x64^</RuntimeIdentifier^> >> !launcherPublishProfile!
echo ^<SelfContained^>false^</SelfContained^> >> !launcherPublishProfile!

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Community.PowerToys.Run.Plugin.UnitConverter</RootNamespace>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows10.0.18362</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{4D971245-7A70-41D5-BAA0-DDB5684CAF51}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Community.PowerToys.Run.Plugin.VSCodeWorkspaces</RootNamespace>
@ -56,6 +56,12 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="Windows.Foundation.UniversalApiContract">
<HintPath>C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0\Windows.Foundation.UniversalApiContract.winmd</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>

View file

@ -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
{

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>x64</Platforms>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.Folder</RootNamespace>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{F8B870EB-D5F5-45BA-9CF7-A5C459818820}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.Indexer</RootNamespace>
@ -53,10 +53,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\settings-ui\Microsoft.PowerToys.Settings.UI.Library\Microsoft.PowerToys.Settings.UI.Library.csproj">
<ProjectReference Include="..\..\..\..\settings-ui\Microsoft.PowerToys.Settings.UI.Library\Microsoft.PowerToys.Settings.UI.Library.csproj" >
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" >
<Private>false</Private>
</ProjectReference>
</ItemGroup>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows10.0.18362</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>

View file

@ -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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("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<IList<Win32Program>>("Win32"), _settings, _pathsToWatch);
RenamedEventArgs e = new RenamedEventArgs(WatcherChangeTypes.Renamed, directory, path, oldpath);
string oldFullPath = directory + "\\" + oldpath;

View file

@ -39,7 +39,7 @@ namespace Microsoft.Plugin.Program
private static PluginInitContext _context;
private readonly PluginJsonStorage<ProgramPluginSettings> _settingsStorage;
private bool _disposed;
private PackageRepository _packageRepository = new PackageRepository(new PackageCatalogWrapper());
private PackageRepository _packageRepository = new PackageRepository(new PackageCatalogWrapper(), new BinaryStorage<IList<UWPApplication>>("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<IFileSystemWatcherWrapper>().ToList(), Settings, _win32ProgramRepositoryHelper.PathsToWatch);
_win32ProgramRepository = new Win32ProgramRepository(_win32ProgramRepositoryHelper.FileSystemWatchers.Cast<IFileSystemWatcherWrapper>().ToList(), new BinaryStorage<IList<Programs.Win32Program>>("Win32"), Settings, _win32ProgramRepositoryHelper.PathsToWatch);
}
public void Save()

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{FDB3555B-58EF-4AE6-B5F1-904719637AB4}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.Program</RootNamespace>
@ -57,10 +57,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" >
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" >
<Private>false</Private>
</ProjectReference>
</ItemGroup>
@ -71,6 +71,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>

View file

@ -39,6 +39,9 @@ namespace Microsoft.Plugin.Program.Programs
InstalledLocation = installedLocation;
}
private static readonly Lazy<bool> IsPackageDotInstallationPathAvailable = new Lazy<bool>(() =>
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;
}
}

View file

@ -7,5 +7,9 @@ namespace Microsoft.Plugin.Program.Storage
internal interface IProgramRepository
{
void IndexPrograms();
void Load();
void Save();
}
}

View file

@ -19,10 +19,13 @@ namespace Microsoft.Plugin.Program.Storage
/// </summary>
internal class PackageRepository : ListRepository<UWPApplication>, IProgramRepository
{
private IStorage<IList<UWPApplication>> _storage;
private IPackageCatalog _packageCatalog;
public PackageRepository(IPackageCatalog packageCatalog)
public PackageRepository(IPackageCatalog packageCatalog, IStorage<IList<UWPApplication>> 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<UWPApplication>());
SetList(items);
}
}
}

View file

@ -24,6 +24,7 @@ namespace Microsoft.Plugin.Program.Storage
private const string LnkExtension = ".lnk";
private const string UrlExtension = ".url";
private IStorage<IList<Programs.Win32Program>> _storage;
private ProgramPluginSettings _settings;
private IList<IFileSystemWatcherWrapper> _fileSystemWatcherHelpers;
private string[] _pathsToWatch;
@ -32,9 +33,10 @@ namespace Microsoft.Plugin.Program.Storage
private static ConcurrentQueue<string> commonEventHandlingQueue = new ConcurrentQueue<string>();
public Win32ProgramRepository(IList<IFileSystemWatcherWrapper> fileSystemWatcherHelpers, ProgramPluginSettings settings, string[] pathsToWatch)
public Win32ProgramRepository(IList<IFileSystemWatcherWrapper> fileSystemWatcherHelpers, IStorage<IList<Win32Program>> 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<Win32Program>());
SetList(items);
}
}
}

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.Shell</RootNamespace>
@ -48,10 +48,10 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" >
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" >
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\Microsoft.Plugin.Folder\Microsoft.Plugin.Folder.csproj">

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>x64</Platforms>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{03276a39-d4e9-417c-8ffd-200b0ee5e871}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.Uri</RootNamespace>
@ -58,10 +58,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" >
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" >
<Private>false</Private>
</ProjectReference>
</ItemGroup>

View file

@ -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")
{

View file

@ -210,6 +210,17 @@ namespace Microsoft.Plugin.WindowWalker.Components
}
}
/// <summary>
/// Gets a value indicating whether determines whether the specified windows is the owner
/// </summary>
public bool IsOwner
{
get
{
return NativeMethods.GetWindow(Hwnd, NativeMethods.GetWindowCmd.GW_OWNER) != null;
}
}
/// <summary>
/// Gets a value indicating whether returns true if the window is minimized
/// </summary>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{74F1B9ED-F59C-4FE7-B473-7B453E30837E}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.WindowWalker</RootNamespace>
@ -60,10 +60,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" >
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" >
<Private>false</Private>
</ProjectReference>
</ItemGroup>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>x64</Platforms>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{59BD9891-3837-438A-958D-ADC7F91F6F7E}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.Calculator</RootNamespace>

View file

@ -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]

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Platforms>x64</Platforms>
<NeutralLanguage>en-US</NeutralLanguage>
<LangVersion>8.0</LangVersion>

View file

@ -65,7 +65,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Classes
/// <param name="key">The <see cref="RegistryKey"/> for this entry.</param>
/// <param name="valueName">The value name of the current selected registry value.</param>
/// <param name="value">The value of the current selected registry value.</param>
internal RegistryEntry(RegistryKey key, string valueName, object? value)
internal RegistryEntry(RegistryKey key, string valueName, object value)
{
KeyPath = key.Name;
Key = key;

View file

@ -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;
}

View file

@ -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)
{

View file

@ -82,7 +82,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper
return new List<Result>(0);
}
ICollection<KeyValuePair<string, object?>> valueList = new List<KeyValuePair<string, object?>>(key.ValueCount);
ICollection<KeyValuePair<string, object>> valueList = new List<KeyValuePair<string, object>>(key.ValueCount);
var resultList = new List<Result>();
@ -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
/// <param name="key">The registry key for the tool-tip</param>
/// <param name="valueEntry">The value name and value of the registry value</param>
/// <returns>A tool-tip text</returns>
private static string GetToolTipTextForRegistryValue(RegistryKey key, KeyValuePair<string, object?> valueEntry)
private static string GetToolTipTextForRegistryValue(RegistryKey key, KeyValuePair<string, object> 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
/// <param name="key">The registry key for the sub-title</param>
/// <param name="valueEntry">The value name and value of the registry value</param>
/// <returns>A sub-title text</returns>
private static string GetSubTileForRegistryValue(RegistryKey key, KeyValuePair<string, object?> valueEntry)
private static string GetSubTileForRegistryValue(RegistryKey key, KeyValuePair<string, object> valueEntry)
{
return $"{Resources.Type} {ValueHelper.GetType(key, valueEntry.Key)}"
+ $" - {Resources.Value} {ValueHelper.GetValue(key, valueEntry.Key, 50)}";

View file

@ -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<byte>()).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}",
};

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.Registry</RootNamespace>
<AssemblyName>Microsoft.PowerToys.Run.Plugin.Registry</AssemblyName>
<Version>$(Version).0</Version>

View file

@ -3,7 +3,7 @@
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.Service</RootNamespace>
<AssemblyName>Microsoft.PowerToys.Run.Plugin.Service</AssemblyName>
<Version>$(Version).0</Version>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>x64</Platforms>

View file

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.System</RootNamespace>
<AssemblyName>Microsoft.PowerToys.Run.Plugin.System</AssemblyName>

View file

@ -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)

View file

@ -65,7 +65,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper
/// <returns>A registry value or <see cref="uint.MinValue"/> on error.</returns>
private static uint GetNumericRegistryValue(in string registryKey, in string valueName)
{
object? registryValueData;
object registryValueData;
try
{

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{5043CECE-E6A7-4867-9CBE-02D27D83747A}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.WindowsSettings</RootNamespace>

View file

@ -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)
{

View file

@ -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)
{
}
}
}

View file

@ -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;
}

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<StartupObject>PowerLauncher.App</StartupObject>
@ -89,31 +89,31 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2021.1.0" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Mages" Version="2.0.0">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.1">
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.0.2" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="6.1.1" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NuGet.CommandLine" Version="5.9.1">
<PackageReference Include="NuGet.CommandLine" Version="5.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SharpZipLib" Version="1.3.2" />
<PackageReference Include="SharpZipLib" Version="1.2.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.7" />
<PackageReference Include="System.Data.OleDb" Version="5.0.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="5.0.0" />
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.6" />
<PackageReference Include="System.Data.OleDb" Version="4.7.1" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.7.0" />
<PackageReference Include="tlbimp-Microsoft.Search.Interop" Version="1.0.0">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="UnitsNet" Version="4.97.1" />
<PackageReference Include="UnitsNet" Version="4.76.0" />
</ItemGroup>
<ItemGroup>

View file

@ -35,6 +35,9 @@ namespace Wox
_themeManager = themeManager ?? throw new ArgumentNullException(nameof(themeManager));
_themeManager.ThemeChanged += OnThemeChanged;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
DesktopNotificationManagerCompat.RegisterActivator<LauncherNotificationActivator>();
DesktopNotificationManagerCompat.RegisterAumidAndComServer<LauncherNotificationActivator>("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);
});
}

View file

@ -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);

View file

@ -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<string, ImageSource> _data = new ConcurrentDictionary<string, ImageSource>();
[NonSerialized]
private readonly WoxJsonStorage<ConcurrentDictionary<string, int>> _usageStorage;
public ConcurrentDictionary<string, int> Usage { get; private set; } = new ConcurrentDictionary<string, int>();
public ImageCache()
{
_usageStorage = new WoxJsonStorage<ConcurrentDictionary<string, int>>("ImageUsageCache");
}
public ImageSource this[string path]
{
get
@ -96,14 +87,9 @@ namespace Wox.Infrastructure.Image
return new Dictionary<string, int>(Usage);
}
public void Initialize()
public void SetUsageAsDictionary(Dictionary<string, int> usage)
{
Usage = _usageStorage.Load();
}
public void Save()
{
_usageStorage.Save();
Usage = new ConcurrentDictionary<string, int>(usage);
}
}
}

View file

@ -29,6 +29,7 @@ namespace Wox.Infrastructure.Image
private static readonly ImageCache ImageCache = new ImageCache();
private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>();
private static BinaryStorage<Dictionary<string, int>> _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<Dictionary<string, int>>("Image");
_hashGenerator = new ImageHashGenerator();
ImageCache.Initialize();
ImageCache.SetUsageAsDictionary(_storage.TryLoad(new Dictionary<string, int>()));
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.

View file

@ -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
{
/// <summary>
/// Storage object using binary data
/// Normally, it has better performance, but not readable
/// </summary>
public class BinaryStorage<T> : IStorage<T>
{
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());
}
}
}

View file

@ -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<T>
{
/// <summary>
/// Saves the data
/// </summary>
/// <param name="data">data to be saved</param>
void Save(T data);
/// <summary>
/// Attempts to load data, otherwise it will return the default provided
/// </summary>
/// <param name="defaultData">default data value</param>
/// <returns>The loaded data or default</returns>
T TryLoad(T defaultData);
}
}

View file

@ -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}");
}
}

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}</ProjectGuid>
<OutputType>Library</OutputType>
<UseWpf>true</UseWpf>

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}</ProjectGuid>
<UseWPF>true</UseWPF>
<OutputType>Library</OutputType>

View file

@ -2,7 +2,7 @@
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows10.0.18362</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{FF742965-9A80-41A5-B042-D6C7D3A21708}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>

View file

@ -30,7 +30,6 @@ map<wstring, vector<wstring>> escapeInfo = {
vector<wstring> 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",