Merge pull request #599 from Flow-Launcher/fix_indexing_notrunning

Fix Windows Index Search service not activated
This commit is contained in:
Kevin Zhang 2021-07-27 17:00:29 +08:00 committed by GitHub
commit 7a355d4dbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 124 additions and 42 deletions

View file

@ -10,6 +10,10 @@
<system:String x:Key="plugin_explorer_deletefilefoldersuccess">Deletion successful</system:String>
<system:String x:Key="plugin_explorer_deletefilefoldersuccess_detail">Successfully deleted the {0}</system:String>
<system:String x:Key="plugin_explorer_globalActionKeywordInvalid">Assigning the global action keyword could bring up too many results during search. Please choose a specific action keyword</system:String>
<system:String x:Key="plugin_explorer_windowsSearchServiceNotRunning">The required service for Windows Index Search does not appear to be running</system:String>
<system:String x:Key="plugin_explorer_windowsSearchServiceFix">To fix this, start the Windows Search service. Select here to remove this warning</system:String>
<system:String x:Key="plugin_explorer_alternative">The warning message has been switched off. As an alternative for searching files and folders, would you like to install Everything plugin?{0}{0}Select 'Yes' to install Everything plugin, or 'No' to return</system:String>
<system:String x:Key="plugin_explorer_alternative_title">Explorer Alternative</system:String>
<!--Controls-->
<system:String x:Key="plugin_explorer_delete">Delete</system:String>

View file

@ -12,14 +12,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
public class SearchManager
{
private readonly PluginInitContext context;
internal static PluginInitContext Context;
private readonly Settings settings;
internal static Settings Settings;
public SearchManager(Settings settings, PluginInitContext context)
{
this.context = context;
this.settings = settings;
Context = context;
Settings = settings;
}
private class PathEqualityComparator : IEqualityComparer<Result>
@ -71,14 +71,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return allowedActionKeyword switch
{
Settings.ActionKeyword.SearchActionKeyword => settings.SearchActionKeywordEnabled &&
keyword == settings.SearchActionKeyword,
Settings.ActionKeyword.PathSearchActionKeyword => settings.PathSearchKeywordEnabled &&
keyword == settings.PathSearchActionKeyword,
Settings.ActionKeyword.SearchActionKeyword => Settings.SearchActionKeywordEnabled &&
keyword == Settings.SearchActionKeyword,
Settings.ActionKeyword.PathSearchActionKeyword => Settings.PathSearchKeywordEnabled &&
keyword == Settings.PathSearchActionKeyword,
Settings.ActionKeyword.FileContentSearchActionKeyword => keyword ==
settings.FileContentSearchActionKeyword,
Settings.ActionKeyword.IndexSearchActionKeyword => settings.IndexOnlySearchKeywordEnabled &&
keyword == settings.IndexSearchActionKeyword
Settings.FileContentSearchActionKeyword,
Settings.ActionKeyword.IndexSearchActionKeyword => Settings.IndexOnlySearchKeywordEnabled &&
keyword == Settings.IndexSearchActionKeyword
};
}
@ -88,18 +88,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search
// This allows the user to type the assigned action keyword and only see the list of quick folder links
if (string.IsNullOrEmpty(query.Search))
return QuickAccess.AccessLinkListAll(query, settings.QuickAccessLinks);
return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks);
var results = new HashSet<Result>(PathEqualityComparator.Instance);
var quickaccessLinks = QuickAccess.AccessLinkListMatched(query, settings.QuickAccessLinks);
var quickaccessLinks = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks);
results.UnionWith(quickaccessLinks);
var isEnvironmentVariable = EnvironmentVariables.IsEnvironmentVariableSearch(querySearch);
if (isEnvironmentVariable)
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(querySearch, query, context);
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(querySearch, query, Context);
// Query is a location path with a full environment variable, eg. %appdata%\somefolder\
var isEnvironmentVariablePath = querySearch[1..].Contains("%\\");
@ -136,22 +136,23 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private async Task<List<Result>> WindowsIndexFileContentSearchAsync(Query query, string querySearchString,
CancellationToken token)
{
var queryConstructor = new QueryConstructor(settings);
var queryConstructor = new QueryConstructor(Settings);
if (string.IsNullOrEmpty(querySearchString))
return new List<Result>();
return await IndexSearch.WindowsIndexSearchAsync(querySearchString,
queryConstructor.CreateQueryHelper().ConnectionString,
return await IndexSearch.WindowsIndexSearchAsync(
querySearchString,
queryConstructor.CreateQueryHelper(),
queryConstructor.QueryForFileContentSearch,
settings.IndexSearchExcludedSubdirectoryPaths,
Settings.IndexSearchExcludedSubdirectoryPaths,
query,
token).ConfigureAwait(false);
}
public bool IsFileContentSearch(string actionKeyword)
{
return actionKeyword == settings.FileContentSearchActionKeyword;
return actionKeyword == Settings.FileContentSearchActionKeyword;
}
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch, CancellationToken token)
@ -176,12 +177,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private async Task<List<Result>> WindowsIndexFilesAndFoldersSearchAsync(Query query, string querySearchString,
CancellationToken token)
{
var queryConstructor = new QueryConstructor(settings);
var queryConstructor = new QueryConstructor(Settings);
return await IndexSearch.WindowsIndexSearchAsync(querySearchString,
queryConstructor.CreateQueryHelper().ConnectionString,
return await IndexSearch.WindowsIndexSearchAsync(
querySearchString,
queryConstructor.CreateQueryHelper(),
queryConstructor.QueryForAllFilesAndFolders,
settings.IndexSearchExcludedSubdirectoryPaths,
Settings.IndexSearchExcludedSubdirectoryPaths,
query,
token).ConfigureAwait(false);
}
@ -189,12 +191,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private async Task<List<Result>> WindowsIndexTopLevelFolderSearchAsync(Query query, string path,
CancellationToken token)
{
var queryConstructor = new QueryConstructor(settings);
var queryConstructor = new QueryConstructor(Settings);
return await IndexSearch.WindowsIndexSearchAsync(path,
queryConstructor.CreateQueryHelper().ConnectionString,
return await IndexSearch.WindowsIndexSearchAsync(
path,
queryConstructor.CreateQueryHelper(),
queryConstructor.QueryForTopLevelDirectorySearch,
settings.IndexSearchExcludedSubdirectoryPaths,
Settings.IndexSearchExcludedSubdirectoryPaths,
query,
token).ConfigureAwait(false);
}
@ -203,10 +206,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
var pathToDirectory = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath);
if (!settings.UseWindowsIndexForDirectorySearch)
if (!Settings.UseWindowsIndexForDirectorySearch)
return false;
if (settings.IndexSearchExcludedSubdirectoryPaths
if (Settings.IndexSearchExcludedSubdirectoryPaths
.Any(x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(pathToDirectory)
.StartsWith(x.Path, StringComparison.OrdinalIgnoreCase)))
return false;

View file

@ -5,9 +5,11 @@ using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
@ -84,22 +86,36 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
return results;
}
internal async static Task<List<Result>> WindowsIndexSearchAsync(string searchString, string connectionString,
Func<string, string> constructQuery,
List<AccessLink> exclusionList,
Query query,
CancellationToken token)
internal async static Task<List<Result>> WindowsIndexSearchAsync(
string searchString,
CSearchQueryHelper queryHelper,
Func<string, string> constructQuery,
List<AccessLink> exclusionList,
Query query,
CancellationToken token)
{
var regexMatch = Regex.Match(searchString, reservedStringPattern);
if (regexMatch.Success)
return new List<Result>();
try
{
var constructedQuery = constructQuery(searchString);
var constructedQuery = constructQuery(searchString);
return RemoveResultsInExclusionList(
await ExecuteWindowsIndexSearchAsync(constructedQuery, connectionString, query, token).ConfigureAwait(false),
return RemoveResultsInExclusionList(
await ExecuteWindowsIndexSearchAsync(constructedQuery, queryHelper.ConnectionString, query, token).ConfigureAwait(false),
exclusionList,
token);
}
catch (COMException)
{
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
if (!SearchManager.Settings.WarnWindowsSearchServiceOff)
return new List<Result>();
return ResultForWindexSearchOff(query.RawQuery);
}
}
private static List<Result> RemoveResultsInExclusionList(List<Result> results, List<AccessLink> exclusionList, CancellationToken token)
@ -137,9 +153,66 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
internal static bool PathIsIndexed(string path)
{
var csm = new CSearchManager();
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
return indexManager.IncludedInCrawlScope(path) > 0;
try
{
var csm = new CSearchManager();
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
return indexManager.IncludedInCrawlScope(path) > 0;
}
catch(COMException)
{
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
return false;
}
}
private static List<Result> ResultForWindexSearchOff(string rawQuery)
{
var api = SearchManager.Context.API;
return new List<Result>
{
new Result
{
Title = api.GetTranslation("plugin_explorer_windowsSearchServiceNotRunning"),
SubTitle = api.GetTranslation("plugin_explorer_windowsSearchServiceFix"),
Action = c =>
{
SearchManager.Settings.WarnWindowsSearchServiceOff = false;
var pluginsManagerPlugin= api.GetAllPlugins().FirstOrDefault(x => x.Metadata.ID == "9f8f9b14-2518-4907-b211-35ab6290dee7");
var actionKeywordCount = pluginsManagerPlugin.Metadata.ActionKeywords.Count;
if (actionKeywordCount > 1)
LogException("PluginsManager's action keyword has increased to more than 1, this does not allow for determining the " +
"right action keyword. Explorer's code for managing Windows Search service not running exception needs to be updated",
new InvalidOperationException());
if (MessageBox.Show(string.Format(api.GetTranslation("plugin_explorer_alternative"), Environment.NewLine),
api.GetTranslation("plugin_explorer_alternative_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes
&& actionKeywordCount == 1)
{
api.ChangeQuery(string.Format("{0} install everything", pluginsManagerPlugin.Metadata.ActionKeywords[0]));
}
else
{
// Clears the warning message because same query string will not alter the displayed result list
api.ChangeQuery(string.Empty);
api.ChangeQuery(rawQuery);
}
var mainWindow = Application.Current.MainWindow;
mainWindow.Visibility = Visibility.Visible;
mainWindow.Focus();
return false;
},
IcoPath = Constants.ExplorerIconImagePath
}
};
}
private static void LogException(string message, Exception e)

View file

@ -1,4 +1,4 @@
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using System;
@ -33,6 +33,8 @@ namespace Flow.Launcher.Plugin.Explorer
public bool IndexOnlySearchKeywordEnabled { get; set; }
public bool WarnWindowsSearchServiceOff { get; set; } = true;
internal enum ActionKeyword
{
SearchActionKeyword,

View file

@ -9,7 +9,7 @@
"Name": "Explorer",
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
"Author": "Jeremy Wu",
"Version": "1.8.0",
"Version": "1.8.1",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",