mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
This reverts commit c651a4b36e.
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0-windows10.0.18362</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,5 +7,9 @@ namespace Microsoft.Plugin.Program.Storage
|
||||
internal interface IProgramRepository
|
||||
{
|
||||
void IndexPrograms();
|
||||
|
||||
void Load();
|
||||
|
||||
void Save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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")
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)}";
|
||||
|
||||
@@ -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}",
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user