mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
* [Dev][Build] .NET 8 Upgrade Silenced errors first fix. * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1859 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1854. * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1860 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1861 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1862 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1863 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1864 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA1865 * [Dev][Build] .NET 8 Upgrade Silenced errors. CA2208 * [Dev][Build] .NET 8 Upgrade Silenced errors. CS9191 * [Dev][Build] .NET 8 Upgrade Silenced errors. Spell check * [Dev][Build] .NET 8 Upgrade Silenced errors. Spell check * [Dev][Build] .NET 8 Upgrade Silenced errors. - CompositeFormat variables used more than once in the same file were assigned to a single variable. - GetProcessesByName logic fix. - String comparion fix. - ArgumentOutOfRangeException message change. * [Dev][Build] .NET 8 Upgrade Silenced errors. - Null check added. - static readonly CompositeFormat added for all fields.
268 lines
10 KiB
C#
268 lines
10 KiB
C#
// 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.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO.Abstractions;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Windows.Controls;
|
|
using ManagedCommon;
|
|
using Microsoft.Plugin.Indexer.DriveDetection;
|
|
using Microsoft.Plugin.Indexer.Interop;
|
|
using Microsoft.Plugin.Indexer.SearchHelper;
|
|
using Microsoft.PowerToys.Settings.UI.Library;
|
|
using Wox.Infrastructure;
|
|
using Wox.Infrastructure.Storage;
|
|
using Wox.Plugin;
|
|
using Wox.Plugin.Logger;
|
|
|
|
namespace Microsoft.Plugin.Indexer
|
|
{
|
|
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin
|
|
{
|
|
private const string DisableDriveDetectionWarning = nameof(DisableDriveDetectionWarning);
|
|
private static readonly IFileSystem _fileSystem = new FileSystem();
|
|
|
|
// This variable contains metadata about the Plugin
|
|
private PluginInitContext _context;
|
|
|
|
// This variable contains information about the context menus
|
|
private IndexerSettings _settings;
|
|
|
|
// Contains information about the plugin stored in json format
|
|
private PluginJsonStorage<IndexerSettings> _storage;
|
|
|
|
// To access Windows Search functionalities
|
|
private static readonly OleDBSearch _search = new OleDBSearch();
|
|
private readonly WindowsSearchAPI _api = new WindowsSearchAPI(_search);
|
|
|
|
// To obtain information regarding the drives that are indexed
|
|
private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper(), new DriveDetection.DriveInfoWrapper());
|
|
|
|
// Reserved keywords in oleDB
|
|
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$|^.*[<>].*$";
|
|
|
|
private string WarningIconPath { get; set; }
|
|
|
|
public string Name => Properties.Resources.Microsoft_plugin_indexer_plugin_name;
|
|
|
|
public string Description => Properties.Resources.Microsoft_plugin_indexer_plugin_description;
|
|
|
|
public static string PluginID => "2140FC9819AD43A3A616E2735815C27C";
|
|
|
|
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
|
|
{
|
|
new PluginAdditionalOption()
|
|
{
|
|
Key = DisableDriveDetectionWarning,
|
|
DisplayLabel = Properties.Resources.disable_drive_detection_warning,
|
|
Value = false,
|
|
},
|
|
};
|
|
|
|
private ContextMenuLoader _contextMenuLoader;
|
|
private bool disposedValue;
|
|
|
|
// To save the configurations of plugins
|
|
public void Save()
|
|
{
|
|
_storage?.Save();
|
|
}
|
|
|
|
// This function uses the Windows indexer and returns the list of results obtained
|
|
public List<Result> Query(Query query, bool isFullQuery)
|
|
{
|
|
var results = new List<Result>();
|
|
|
|
if (!string.IsNullOrEmpty(query.Search))
|
|
{
|
|
var searchQuery = query.Search;
|
|
if (_settings.MaxSearchCount <= 0)
|
|
{
|
|
_settings.MaxSearchCount = 30;
|
|
}
|
|
|
|
var regexMatch = Regex.Match(searchQuery, reservedStringPattern);
|
|
|
|
if (!regexMatch.Success)
|
|
{
|
|
try
|
|
{
|
|
if (_driveDetection.DisplayWarning())
|
|
{
|
|
results.Add(new Result
|
|
{
|
|
Title = Properties.Resources.Microsoft_plugin_indexer_drivedetectionwarning,
|
|
SubTitle = Properties.Resources.Microsoft_plugin_indexer_disable_warning_in_settings,
|
|
IcoPath = WarningIconPath,
|
|
Action = e =>
|
|
{
|
|
Helper.OpenInShell("ms-settings:cortana-windowssearch");
|
|
return true;
|
|
},
|
|
});
|
|
}
|
|
|
|
// This uses the Microsoft.Search.Interop assembly
|
|
var searchManager = new CSearchManager();
|
|
var searchResultsList = _api.Search(searchQuery, searchManager, maxCount: _settings.MaxSearchCount).ToList();
|
|
|
|
// If the delayed execution query is not required (since the SQL query is fast) return empty results
|
|
if (searchResultsList.Count == 0 && isFullQuery)
|
|
{
|
|
return new List<Result>();
|
|
}
|
|
|
|
foreach (var searchResult in searchResultsList)
|
|
{
|
|
var path = searchResult.Path;
|
|
|
|
// Using CurrentCulture since this is user facing
|
|
var toolTipTitle = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", Properties.Resources.Microsoft_plugin_indexer_name, searchResult.Title);
|
|
var toolTipText = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", Properties.Resources.Microsoft_plugin_indexer_path, path);
|
|
string workingDir = null;
|
|
if (_settings.UseLocationAsWorkingDir)
|
|
{
|
|
workingDir = _fileSystem.Path.GetDirectoryName(path);
|
|
}
|
|
|
|
Result r = new Result();
|
|
r.Title = searchResult.Title;
|
|
r.SubTitle = Properties.Resources.Microsoft_plugin_indexer_subtitle_header + ": " + path;
|
|
r.IcoPath = path;
|
|
r.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);
|
|
r.Action = c =>
|
|
{
|
|
bool hide = true;
|
|
if (!Helper.OpenInShell(path, null, workingDir))
|
|
{
|
|
hide = false;
|
|
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
|
var msg = Properties.Resources.Microsoft_plugin_indexer_file_open_failed;
|
|
_context.API.ShowMsg(name, msg, string.Empty);
|
|
}
|
|
|
|
return hide;
|
|
};
|
|
r.ContextData = searchResult;
|
|
|
|
// If the result is a directory, then it's display should show a directory.
|
|
if (_fileSystem.Directory.Exists(path))
|
|
{
|
|
r.QueryTextDisplay = path;
|
|
}
|
|
|
|
results.Add(r);
|
|
}
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
// The connection has closed, internal error of ExecuteReader()
|
|
// Not showing this exception to the users
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Exception("Something failed", ex, GetType());
|
|
}
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
// This function uses the Windows indexer and returns the list of results obtained. This version is required to implement the interface
|
|
public List<Result> Query(Query query)
|
|
{
|
|
// All plugins have to implement IPlugin interface. We return empty collection as we do not want any computation with constant search plugins.
|
|
return new List<Result>();
|
|
}
|
|
|
|
public void Init(PluginInitContext context)
|
|
{
|
|
// initialize the context of the plugin
|
|
_context = context;
|
|
_contextMenuLoader = new ContextMenuLoader(context);
|
|
_storage = new PluginJsonStorage<IndexerSettings>();
|
|
_settings = _storage.Load();
|
|
_context.API.ThemeChanged += OnThemeChanged;
|
|
UpdateIconPath(_context.API.GetCurrentTheme());
|
|
}
|
|
|
|
// Todo : Update with theme based IconPath
|
|
private void UpdateIconPath(Theme theme)
|
|
{
|
|
if (theme == Theme.Light || theme == Theme.HighContrastWhite)
|
|
{
|
|
WarningIconPath = "Images/Warning.light.png";
|
|
}
|
|
else
|
|
{
|
|
WarningIconPath = "Images/Warning.dark.png";
|
|
}
|
|
}
|
|
|
|
private void OnThemeChanged(Theme currentTheme, Theme newTheme)
|
|
{
|
|
UpdateIconPath(newTheme);
|
|
}
|
|
|
|
// Set the Plugin Title
|
|
public string GetTranslatedPluginTitle()
|
|
{
|
|
return Properties.Resources.Microsoft_plugin_indexer_plugin_name;
|
|
}
|
|
|
|
// Set the plugin Description
|
|
public string GetTranslatedPluginDescription()
|
|
{
|
|
return Properties.Resources.Microsoft_plugin_indexer_plugin_description;
|
|
}
|
|
|
|
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
|
{
|
|
return _contextMenuLoader.LoadContextMenus(selectedResult);
|
|
}
|
|
|
|
public void UpdateSettings(PowerLauncherPluginSettings settings)
|
|
{
|
|
var driveDetection = false;
|
|
|
|
if (settings.AdditionalOptions != null)
|
|
{
|
|
var option = settings.AdditionalOptions.FirstOrDefault(x => x.Key == DisableDriveDetectionWarning);
|
|
|
|
driveDetection = option == null ? false : option.Value;
|
|
}
|
|
|
|
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = driveDetection;
|
|
}
|
|
|
|
public Control CreateSettingPanel()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!disposedValue)
|
|
{
|
|
if (disposing)
|
|
{
|
|
}
|
|
|
|
disposedValue = true;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
Dispose(disposing: true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
}
|