Skip to content

Commit 7a355d4

Browse files
authored
Merge pull request #599 from Flow-Launcher/fix_indexing_notrunning
Fix Windows Index Search service not activated
2 parents 311b83c + bd15aa7 commit 7a355d4

File tree

5 files changed

+124
-42
lines changed

5 files changed

+124
-42
lines changed

Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
<system:String x:Key="plugin_explorer_deletefilefoldersuccess">Deletion successful</system:String>
1111
<system:String x:Key="plugin_explorer_deletefilefoldersuccess_detail">Successfully deleted the {0}</system:String>
1212
<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>
13+
<system:String x:Key="plugin_explorer_windowsSearchServiceNotRunning">The required service for Windows Index Search does not appear to be running</system:String>
14+
<system:String x:Key="plugin_explorer_windowsSearchServiceFix">To fix this, start the Windows Search service. Select here to remove this warning</system:String>
15+
<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>
16+
<system:String x:Key="plugin_explorer_alternative_title">Explorer Alternative</system:String>
1317

1418
<!--Controls-->
1519
<system:String x:Key="plugin_explorer_delete">Delete</system:String>

Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
1212
{
1313
public class SearchManager
1414
{
15-
private readonly PluginInitContext context;
15+
internal static PluginInitContext Context;
1616

17-
private readonly Settings settings;
17+
internal static Settings Settings;
1818

1919
public SearchManager(Settings settings, PluginInitContext context)
2020
{
21-
this.context = context;
22-
this.settings = settings;
21+
Context = context;
22+
Settings = settings;
2323
}
2424

2525
private class PathEqualityComparator : IEqualityComparer<Result>
@@ -71,14 +71,14 @@ private bool ActionKeywordMatch(Query query, Settings.ActionKeyword allowedActio
7171

7272
return allowedActionKeyword switch
7373
{
74-
Settings.ActionKeyword.SearchActionKeyword => settings.SearchActionKeywordEnabled &&
75-
keyword == settings.SearchActionKeyword,
76-
Settings.ActionKeyword.PathSearchActionKeyword => settings.PathSearchKeywordEnabled &&
77-
keyword == settings.PathSearchActionKeyword,
74+
Settings.ActionKeyword.SearchActionKeyword => Settings.SearchActionKeywordEnabled &&
75+
keyword == Settings.SearchActionKeyword,
76+
Settings.ActionKeyword.PathSearchActionKeyword => Settings.PathSearchKeywordEnabled &&
77+
keyword == Settings.PathSearchActionKeyword,
7878
Settings.ActionKeyword.FileContentSearchActionKeyword => keyword ==
79-
settings.FileContentSearchActionKeyword,
80-
Settings.ActionKeyword.IndexSearchActionKeyword => settings.IndexOnlySearchKeywordEnabled &&
81-
keyword == settings.IndexSearchActionKeyword
79+
Settings.FileContentSearchActionKeyword,
80+
Settings.ActionKeyword.IndexSearchActionKeyword => Settings.IndexOnlySearchKeywordEnabled &&
81+
keyword == Settings.IndexSearchActionKeyword
8282
};
8383
}
8484

@@ -88,18 +88,18 @@ public async Task<List<Result>> PathSearchAsync(Query query, CancellationToken t
8888

8989
// This allows the user to type the assigned action keyword and only see the list of quick folder links
9090
if (string.IsNullOrEmpty(query.Search))
91-
return QuickAccess.AccessLinkListAll(query, settings.QuickAccessLinks);
91+
return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks);
9292

9393
var results = new HashSet<Result>(PathEqualityComparator.Instance);
9494

95-
var quickaccessLinks = QuickAccess.AccessLinkListMatched(query, settings.QuickAccessLinks);
95+
var quickaccessLinks = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks);
9696

9797
results.UnionWith(quickaccessLinks);
9898

9999
var isEnvironmentVariable = EnvironmentVariables.IsEnvironmentVariableSearch(querySearch);
100100

101101
if (isEnvironmentVariable)
102-
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(querySearch, query, context);
102+
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(querySearch, query, Context);
103103

104104
// Query is a location path with a full environment variable, eg. %appdata%\somefolder\
105105
var isEnvironmentVariablePath = querySearch[1..].Contains("%\\");
@@ -136,22 +136,23 @@ public async Task<List<Result>> PathSearchAsync(Query query, CancellationToken t
136136
private async Task<List<Result>> WindowsIndexFileContentSearchAsync(Query query, string querySearchString,
137137
CancellationToken token)
138138
{
139-
var queryConstructor = new QueryConstructor(settings);
139+
var queryConstructor = new QueryConstructor(Settings);
140140

141141
if (string.IsNullOrEmpty(querySearchString))
142142
return new List<Result>();
143143

144-
return await IndexSearch.WindowsIndexSearchAsync(querySearchString,
145-
queryConstructor.CreateQueryHelper().ConnectionString,
144+
return await IndexSearch.WindowsIndexSearchAsync(
145+
querySearchString,
146+
queryConstructor.CreateQueryHelper(),
146147
queryConstructor.QueryForFileContentSearch,
147-
settings.IndexSearchExcludedSubdirectoryPaths,
148+
Settings.IndexSearchExcludedSubdirectoryPaths,
148149
query,
149150
token).ConfigureAwait(false);
150151
}
151152

152153
public bool IsFileContentSearch(string actionKeyword)
153154
{
154-
return actionKeyword == settings.FileContentSearchActionKeyword;
155+
return actionKeyword == Settings.FileContentSearchActionKeyword;
155156
}
156157

157158
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch, CancellationToken token)
@@ -176,25 +177,27 @@ public async Task<List<Result>> TopLevelDirectorySearchBehaviourAsync(
176177
private async Task<List<Result>> WindowsIndexFilesAndFoldersSearchAsync(Query query, string querySearchString,
177178
CancellationToken token)
178179
{
179-
var queryConstructor = new QueryConstructor(settings);
180+
var queryConstructor = new QueryConstructor(Settings);
180181

181-
return await IndexSearch.WindowsIndexSearchAsync(querySearchString,
182-
queryConstructor.CreateQueryHelper().ConnectionString,
182+
return await IndexSearch.WindowsIndexSearchAsync(
183+
querySearchString,
184+
queryConstructor.CreateQueryHelper(),
183185
queryConstructor.QueryForAllFilesAndFolders,
184-
settings.IndexSearchExcludedSubdirectoryPaths,
186+
Settings.IndexSearchExcludedSubdirectoryPaths,
185187
query,
186188
token).ConfigureAwait(false);
187189
}
188190

189191
private async Task<List<Result>> WindowsIndexTopLevelFolderSearchAsync(Query query, string path,
190192
CancellationToken token)
191193
{
192-
var queryConstructor = new QueryConstructor(settings);
194+
var queryConstructor = new QueryConstructor(Settings);
193195

194-
return await IndexSearch.WindowsIndexSearchAsync(path,
195-
queryConstructor.CreateQueryHelper().ConnectionString,
196+
return await IndexSearch.WindowsIndexSearchAsync(
197+
path,
198+
queryConstructor.CreateQueryHelper(),
196199
queryConstructor.QueryForTopLevelDirectorySearch,
197-
settings.IndexSearchExcludedSubdirectoryPaths,
200+
Settings.IndexSearchExcludedSubdirectoryPaths,
198201
query,
199202
token).ConfigureAwait(false);
200203
}
@@ -203,10 +206,10 @@ private bool UseWindowsIndexForDirectorySearch(string locationPath)
203206
{
204207
var pathToDirectory = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath);
205208

206-
if (!settings.UseWindowsIndexForDirectorySearch)
209+
if (!Settings.UseWindowsIndexForDirectorySearch)
207210
return false;
208211

209-
if (settings.IndexSearchExcludedSubdirectoryPaths
212+
if (Settings.IndexSearchExcludedSubdirectoryPaths
210213
.Any(x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(pathToDirectory)
211214
.StartsWith(x.Path, StringComparison.OrdinalIgnoreCase)))
212215
return false;

Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
using System.Collections.Generic;
66
using System.Data.OleDb;
77
using System.Linq;
8+
using System.Runtime.InteropServices;
89
using System.Text.RegularExpressions;
910
using System.Threading;
1011
using System.Threading.Tasks;
12+
using System.Windows;
1113

1214
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
1315
{
@@ -84,22 +86,36 @@ internal static async Task<List<Result>> ExecuteWindowsIndexSearchAsync(string i
8486
return results;
8587
}
8688

87-
internal async static Task<List<Result>> WindowsIndexSearchAsync(string searchString, string connectionString,
88-
Func<string, string> constructQuery,
89-
List<AccessLink> exclusionList,
90-
Query query,
91-
CancellationToken token)
89+
internal async static Task<List<Result>> WindowsIndexSearchAsync(
90+
string searchString,
91+
CSearchQueryHelper queryHelper,
92+
Func<string, string> constructQuery,
93+
List<AccessLink> exclusionList,
94+
Query query,
95+
CancellationToken token)
9296
{
9397
var regexMatch = Regex.Match(searchString, reservedStringPattern);
9498

9599
if (regexMatch.Success)
96100
return new List<Result>();
101+
102+
try
103+
{
104+
var constructedQuery = constructQuery(searchString);
97105

98-
var constructedQuery = constructQuery(searchString);
99-
return RemoveResultsInExclusionList(
100-
await ExecuteWindowsIndexSearchAsync(constructedQuery, connectionString, query, token).ConfigureAwait(false),
106+
return RemoveResultsInExclusionList(
107+
await ExecuteWindowsIndexSearchAsync(constructedQuery, queryHelper.ConnectionString, query, token).ConfigureAwait(false),
101108
exclusionList,
102109
token);
110+
}
111+
catch (COMException)
112+
{
113+
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
114+
if (!SearchManager.Settings.WarnWindowsSearchServiceOff)
115+
return new List<Result>();
116+
117+
return ResultForWindexSearchOff(query.RawQuery);
118+
}
103119
}
104120

105121
private static List<Result> RemoveResultsInExclusionList(List<Result> results, List<AccessLink> exclusionList, CancellationToken token)
@@ -137,9 +153,66 @@ private static List<Result> RemoveResultsInExclusionList(List<Result> results, L
137153

138154
internal static bool PathIsIndexed(string path)
139155
{
140-
var csm = new CSearchManager();
141-
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
142-
return indexManager.IncludedInCrawlScope(path) > 0;
156+
try
157+
{
158+
var csm = new CSearchManager();
159+
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
160+
return indexManager.IncludedInCrawlScope(path) > 0;
161+
}
162+
catch(COMException)
163+
{
164+
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
165+
return false;
166+
}
167+
}
168+
169+
private static List<Result> ResultForWindexSearchOff(string rawQuery)
170+
{
171+
var api = SearchManager.Context.API;
172+
173+
return new List<Result>
174+
{
175+
new Result
176+
{
177+
Title = api.GetTranslation("plugin_explorer_windowsSearchServiceNotRunning"),
178+
SubTitle = api.GetTranslation("plugin_explorer_windowsSearchServiceFix"),
179+
Action = c =>
180+
{
181+
SearchManager.Settings.WarnWindowsSearchServiceOff = false;
182+
183+
var pluginsManagerPlugin= api.GetAllPlugins().FirstOrDefault(x => x.Metadata.ID == "9f8f9b14-2518-4907-b211-35ab6290dee7");
184+
185+
var actionKeywordCount = pluginsManagerPlugin.Metadata.ActionKeywords.Count;
186+
187+
if (actionKeywordCount > 1)
188+
LogException("PluginsManager's action keyword has increased to more than 1, this does not allow for determining the " +
189+
"right action keyword. Explorer's code for managing Windows Search service not running exception needs to be updated",
190+
new InvalidOperationException());
191+
192+
if (MessageBox.Show(string.Format(api.GetTranslation("plugin_explorer_alternative"), Environment.NewLine),
193+
api.GetTranslation("plugin_explorer_alternative_title"),
194+
MessageBoxButton.YesNo) == MessageBoxResult.Yes
195+
&& actionKeywordCount == 1)
196+
{
197+
api.ChangeQuery(string.Format("{0} install everything", pluginsManagerPlugin.Metadata.ActionKeywords[0]));
198+
}
199+
else
200+
{
201+
// Clears the warning message because same query string will not alter the displayed result list
202+
api.ChangeQuery(string.Empty);
203+
204+
api.ChangeQuery(rawQuery);
205+
}
206+
207+
var mainWindow = Application.Current.MainWindow;
208+
mainWindow.Visibility = Visibility.Visible;
209+
mainWindow.Focus();
210+
211+
return false;
212+
},
213+
IcoPath = Constants.ExplorerIconImagePath
214+
}
215+
};
143216
}
144217

145218
private static void LogException(string message, Exception e)

Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Flow.Launcher.Plugin.Explorer.Search;
1+
using Flow.Launcher.Plugin.Explorer.Search;
22
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
33
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
44
using System;
@@ -33,6 +33,8 @@ public class Settings
3333

3434
public bool IndexOnlySearchKeywordEnabled { get; set; }
3535

36+
public bool WarnWindowsSearchServiceOff { get; set; } = true;
37+
3638
internal enum ActionKeyword
3739
{
3840
SearchActionKeyword,

Plugins/Flow.Launcher.Plugin.Explorer/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"Name": "Explorer",
1010
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
1111
"Author": "Jeremy Wu",
12-
"Version": "1.8.0",
12+
"Version": "1.8.1",
1313
"Language": "csharp",
1414
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
1515
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",

0 commit comments

Comments
 (0)