diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/EverythingSDK/Everything64.dll b/Plugins/Flow.Launcher.Plugin.Explorer/EverythingSDK/Everything64.dll
new file mode 100644
index 000000000..6d093b793
Binary files /dev/null and b/Plugins/Flow.Launcher.Plugin.Explorer/EverythingSDK/Everything64.dll differ
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/EverythingSDK/Everything86.dll b/Plugins/Flow.Launcher.Plugin.Explorer/EverythingSDK/Everything86.dll
new file mode 100644
index 000000000..de73b87d1
Binary files /dev/null and b/Plugins/Flow.Launcher.Plugin.Explorer/EverythingSDK/Everything86.dll differ
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
index b4ab89a36..ae48ac3ee 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
@@ -35,6 +35,9 @@
Designer
PreserveNewest
+
+ PreserveNewest
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
index 60208759e..d8879a4f6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -1,9 +1,12 @@
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Explorer.Search;
+using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using Flow.Launcher.Plugin.Explorer.ViewModels;
using Flow.Launcher.Plugin.Explorer.Views;
+using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -47,7 +50,8 @@ namespace Flow.Launcher.Plugin.Explorer
contextMenu = new ContextMenu(Context, Settings, viewModel);
searchManager = new SearchManager(Settings, Context);
ResultManager.Init(Context, Settings);
-
+ EverythingApiDllImport.Load(Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "EverythingSDK",
+ Environment.Is64BitProcess ? "Everything64.dll" : "Everything86.dll"));
return Task.CompletedTask;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
new file mode 100644
index 000000000..089a0f8ff
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
@@ -0,0 +1,193 @@
+using Flow.Launcher.Plugin.Everything.Everything;
+using Flow.Launcher.Plugin.Everything.Everything.Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin.Explorer.Search.Everything
+{
+
+ public static class EverythingApi
+ {
+
+ private const int BufferSize = 4096;
+
+ private static readonly object syncObject = new object();
+ // cached buffer to remove redundant allocations.
+ private static readonly StringBuilder buffer = new StringBuilder(BufferSize);
+
+ public enum StateCode
+ {
+ OK,
+ MemoryError,
+ IPCError,
+ RegisterClassExError,
+ CreateWindowError,
+ CreateThreadError,
+ InvalidIndexError,
+ InvalidCallError
+ }
+
+ ///
+ /// Gets or sets a value indicating whether [match path].
+ ///
+ /// true if [match path]; otherwise, false.
+ public static bool MatchPath
+ {
+ get => EverythingApiDllImport.Everything_GetMatchPath();
+ set => EverythingApiDllImport.Everything_SetMatchPath(value);
+ }
+
+ ///
+ /// Gets or sets a value indicating whether [match case].
+ ///
+ /// true if [match case]; otherwise, false.
+ public static bool MatchCase
+ {
+ get => EverythingApiDllImport.Everything_GetMatchCase();
+ set => EverythingApiDllImport.Everything_SetMatchCase(value);
+ }
+
+ ///
+ /// Gets or sets a value indicating whether [match whole word].
+ ///
+ /// true if [match whole word]; otherwise, false.
+ public static bool MatchWholeWord
+ {
+ get => EverythingApiDllImport.Everything_GetMatchWholeWord();
+ set => EverythingApiDllImport.Everything_SetMatchWholeWord(value);
+ }
+
+ ///
+ /// Gets or sets a value indicating whether [enable regex].
+ ///
+ /// true if [enable regex]; otherwise, false.
+ public static bool EnableRegex
+ {
+ get => EverythingApiDllImport.Everything_GetRegex();
+ set => EverythingApiDllImport.Everything_SetRegex(value);
+ }
+
+ ///
+ /// Resets this instance.
+ ///
+ private static void Reset()
+ {
+ lock (syncObject)
+ {
+ EverythingApiDllImport.Everything_Reset();
+ }
+ }
+
+ ///
+ /// Checks whether the sort option is Fast Sort.
+ ///
+ public static bool IsFastSortOption(SortOption sortOption)
+ {
+ var fastSortOptionEnabled = EverythingApiDllImport.Everything_IsFastSort(sortOption);
+
+ // If the Everything service is not running, then this call will incorrectly report
+ // the state as false. This checks for errors thrown by the api and up to the caller to handle.
+ CheckAndThrowExceptionOnError();
+
+ return fastSortOptionEnabled;
+ }
+
+ ///
+ /// Searches the specified key word and reset the everything API afterwards
+ ///
+ /// The key word.
+ /// when cancelled the current search will stop and exit (and would not reset)
+ /// Sort By
+ /// The offset.
+ /// The max count.
+ ///
+ public static IEnumerable SearchAsync(string keyword, CancellationToken token, SortOption sortOption = SortOption.NAME_ASCENDING, int offset = 0, int maxCount = 100)
+ {
+ if (string.IsNullOrEmpty(keyword))
+ throw new ArgumentNullException(nameof(keyword));
+
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset));
+
+ if (maxCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(maxCount));
+
+ lock (syncObject)
+ {
+ if (keyword.StartsWith("@"))
+ {
+ EverythingApiDllImport.Everything_SetRegex(true);
+ keyword = keyword[1..];
+ }
+
+ EverythingApiDllImport.Everything_SetSearchW(keyword);
+ EverythingApiDllImport.Everything_SetOffset(offset);
+ EverythingApiDllImport.Everything_SetMax(maxCount);
+
+ EverythingApiDllImport.Everything_SetSort(sortOption);
+
+ if (token.IsCancellationRequested)
+ {
+ return null;
+ }
+
+
+ if (!EverythingApiDllImport.Everything_QueryW(true))
+ {
+ CheckAndThrowExceptionOnError();
+ return null;
+ }
+
+ var results = new List();
+ for (var idx = 0; idx < EverythingApiDllImport.Everything_GetNumResults(); ++idx)
+ {
+ if (token.IsCancellationRequested)
+ {
+ return null;
+ }
+
+ EverythingApiDllImport.Everything_GetResultFullPathNameW(idx, buffer, BufferSize);
+
+ var result = new SearchResult
+ {
+ FullPath = buffer.ToString(),
+ Type = EverythingApiDllImport.Everything_IsFolderResult(idx) ? ResultType.Folder :
+ EverythingApiDllImport.Everything_IsFileResult(idx) ? ResultType.File :
+ ResultType.Volume
+ };
+
+ results.Add(result);
+ }
+
+ Reset();
+
+ return results;
+ }
+ }
+
+ private static void CheckAndThrowExceptionOnError()
+ {
+ switch (EverythingApiDllImport.Everything_GetLastError())
+ {
+ case StateCode.CreateThreadError:
+ throw new CreateThreadException();
+ case StateCode.CreateWindowError:
+ throw new CreateWindowException();
+ case StateCode.InvalidCallError:
+ throw new InvalidCallException();
+ case StateCode.InvalidIndexError:
+ throw new InvalidIndexException();
+ case StateCode.IPCError:
+ throw new IPCErrorException();
+ case StateCode.MemoryError:
+ throw new MemoryErrorException();
+ case StateCode.RegisterClassExError:
+ throw new RegisterClassExException();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs
new file mode 100644
index 000000000..b100a6026
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs
@@ -0,0 +1,153 @@
+using Flow.Launcher.Plugin.Everything.Everything;
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Flow.Launcher.Plugin.Explorer.Search.Everything
+{
+ public static class EverythingApiDllImport
+ {
+ public static void Load(string path)
+ {
+ LoadLibrary(path);
+ }
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ private static extern int LoadLibrary(string name);
+
+ private const string DLL = "Everything.dll";
+
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ internal static extern int Everything_SetSearchW(string lpSearchString);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SetMatchPath(bool bEnable);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SetMatchCase(bool bEnable);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SetMatchWholeWord(bool bEnable);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SetRegex(bool bEnable);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SetMax(int dwMax);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SetOffset(int dwOffset);
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_GetMatchPath();
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_GetMatchCase();
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_GetMatchWholeWord();
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_GetRegex();
+
+ [DllImport(DLL)]
+ internal static extern uint Everything_GetMax();
+
+ [DllImport(DLL)]
+ internal static extern uint Everything_GetOffset();
+
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ internal static extern string Everything_GetSearchW();
+
+ [DllImport(DLL)]
+ internal static extern EverythingApi.StateCode Everything_GetLastError();
+
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ internal static extern bool Everything_QueryW(bool bWait);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_SortResultsByPath();
+
+ [DllImport(DLL)]
+ internal static extern int Everything_GetNumFileResults();
+
+ [DllImport(DLL)]
+ internal static extern int Everything_GetNumFolderResults();
+
+ [DllImport(DLL)]
+ internal static extern int Everything_GetNumResults();
+
+ [DllImport(DLL)]
+ internal static extern int Everything_GetTotFileResults();
+
+ [DllImport(DLL)]
+ internal static extern int Everything_GetTotFolderResults();
+
+ [DllImport(DLL)]
+ internal static extern int Everything_GetTotResults();
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_IsVolumeResult(int nIndex);
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_IsFolderResult(int nIndex);
+
+ [DllImport(DLL)]
+ internal static extern bool Everything_IsFileResult(int nIndex);
+
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ internal static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);
+
+ [DllImport(DLL)]
+ internal static extern void Everything_Reset();
+
+ // Everything 1.4
+
+ [DllImport(DLL)]
+ public static extern void Everything_SetSort(SortOption dwSortType);
+ [DllImport(DLL)]
+ public static extern bool Everything_IsFastSort(SortOption dwSortType);
+ [DllImport(DLL)]
+ public static extern SortOption Everything_GetSort();
+ [DllImport(DLL)]
+ public static extern uint Everything_GetResultListSort();
+ [DllImport(DLL)]
+ public static extern void Everything_SetRequestFlags(uint dwRequestFlags);
+ [DllImport(DLL)]
+ public static extern uint Everything_GetRequestFlags();
+ [DllImport(DLL)]
+ public static extern uint Everything_GetResultListRequestFlags();
+ [DllImport("Everything64.dll", CharSet = CharSet.Unicode)]
+ public static extern IntPtr Everything_GetResultExtension(uint nIndex);
+ [DllImport(DLL)]
+ public static extern bool Everything_GetResultSize(uint nIndex, out long lpFileSize);
+ [DllImport(DLL)]
+ public static extern bool Everything_GetResultDateCreated(uint nIndex, out long lpFileTime);
+ [DllImport(DLL)]
+ public static extern bool Everything_GetResultDateModified(uint nIndex, out long lpFileTime);
+ [DllImport(DLL)]
+ public static extern bool Everything_GetResultDateAccessed(uint nIndex, out long lpFileTime);
+ [DllImport(DLL)]
+ public static extern uint Everything_GetResultAttributes(uint nIndex);
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ public static extern IntPtr Everything_GetResultFileListFileName(uint nIndex);
+ [DllImport(DLL)]
+ public static extern uint Everything_GetResultRunCount(uint nIndex);
+ [DllImport(DLL)]
+ public static extern bool Everything_GetResultDateRun(uint nIndex, out long lpFileTime);
+ [DllImport(DLL)]
+ public static extern bool Everything_GetResultDateRecentlyChanged(uint nIndex, out long lpFileTime);
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ public static extern IntPtr Everything_GetResultHighlightedFileName(uint nIndex);
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ public static extern IntPtr Everything_GetResultHighlightedPath(uint nIndex);
+ [DllImport(DLL, CharSet = CharSet.Unicode)]
+ public static extern IntPtr Everything_GetResultHighlightedFullPathAndFileName(uint nIndex);
+ [DllImport(DLL)]
+ public static extern uint Everything_GetRunCountFromFileName(string lpFileName);
+ [DllImport(DLL)]
+ public static extern bool Everything_SetRunCountFromFileName(string lpFileName, uint dwRunCount);
+ [DllImport(DLL)]
+ public static extern uint Everything_IncRunCountFromFileName(string lpFileName);
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs
new file mode 100644
index 000000000..e1486f9fb
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingSearchManager.cs
@@ -0,0 +1,27 @@
+using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin.Explorer.Search.Everything
+{
+ public class EverythingSearchManager : IIndexProvider
+ {
+ private Settings Settings { get; }
+
+ public EverythingSearchManager(Settings settings)
+ {
+ Settings = settings;
+ }
+
+
+ public ValueTask> SearchAsync(Query query, CancellationToken token)
+ {
+ return ValueTask.FromResult(EverythingApi.SearchAsync(query.Search, token, Settings.SortOption));
+ }
+ public ValueTask> ContentSearchAsync(Query query, CancellationToken token)
+ {
+ return new ValueTask>(new List());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/SortOption.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/SortOption.cs
new file mode 100644
index 000000000..434afd1b4
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/SortOption.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin.Everything.Everything
+{
+ public enum SortOption : uint
+ {
+ NAME_ASCENDING = 1u,
+ NAME_DESCENDING = 2u,
+ PATH_ASCENDING = 3u,
+ PATH_DESCENDING = 4u,
+ SIZE_ASCENDING = 5u,
+ SIZE_DESCENDING = 6u,
+ EXTENSION_ASCENDING = 7u,
+ EXTENSION_DESCENDING = 8u,
+ TYPE_NAME_ASCENDING = 9u,
+ TYPE_NAME_DESCENDING = 10u,
+ DATE_CREATED_ASCENDING = 11u,
+ DATE_CREATED_DESCENDING = 12u,
+ DATE_MODIFIED_ASCENDING = 13u,
+ DATE_MODIFIED_DESCENDING = 14u,
+ ATTRIBUTES_ASCENDING = 15u,
+ ATTRIBUTES_DESCENDING = 16u,
+ FILE_LIST_FILENAME_ASCENDING = 17u,
+ FILE_LIST_FILENAME_DESCENDING = 18u,
+ RUN_COUNT_ASCENDING = 19u,
+ RUN_COUNT_DESCENDING = 20u,
+ DATE_RECENTLY_CHANGED_ASCENDING = 21u,
+ DATE_RECENTLY_CHANGED_DESCENDING = 22u,
+ DATE_ACCESSED_ASCENDING = 23u,
+ DATE_ACCESSED_DESCENDING = 24u,
+ DATE_RUN_ASCENDING = 25u,
+ DATE_RUN_DESCENDING = 26u
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/IPathEnumerable.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/IPathEnumerable.cs
new file mode 100644
index 000000000..d7f0a8ec8
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/IPathEnumerable.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Flow.Launcher.Plugin.Explorer.Search
+{
+ public interface IPathEnumerable
+ {
+ public IEnumerable Enumerate(string path, bool recursive);
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 63310bebd..35ba0bafb 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -35,6 +35,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return $"{keyword}{formatted_path}";
}
+ public static Result CreateResult(Query query, SearchResult result)
+ {
+ return result.Type switch
+ {
+ ResultType.Folder or ResultType.Volume => CreateFolderResult(Path.GetFileName(result.FullPath),
+ result.FullPath, result.FullPath, query, 0, result.ShowIndexState, result.WindowsIndexed),
+ ResultType.File => CreateFileResult(
+ result.FullPath, query, 0, result.ShowIndexState, result.WindowsIndexed),
+ _ => throw new ArgumentOutOfRangeException()
+ };
+ }
+
internal static Result CreateFolderResult(string title, string subtitle, string path, Query query, int score = 0, bool showIndexState = false, bool windowsIndexed = false)
{
return new Result
@@ -61,7 +73,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
Context.API.ChangeQuery(GetPathWithActionKeyword(path, ResultType.Folder));
-
+
return false;
},
Score = score,
@@ -192,16 +204,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
}
- internal class SearchResult
- {
- public string FullPath { get; set; }
- public ResultType Type { get; set; }
-
- public bool WindowsIndexed { get; set; }
-
- public bool ShowIndexState { get; set; }
- }
-
public enum ResultType
{
Volume,
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
index 8ce627a44..080621f42 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
@@ -57,8 +57,16 @@ namespace Flow.Launcher.Plugin.Explorer.Search
results.UnionWith(quickaccessLinks);
}
+ IEnumerable searchResults;
+
if (IsFileContentSearch(query.ActionKeyword))
- return await WindowsIndexFileContentSearchAsync(query, querySearch, token).ConfigureAwait(false);
+ {
+ searchResults = await Settings.IndexProvider.ContentSearchAsync(query, token);
+ }
+ else
+ {
+ searchResults = await Settings.IndexProvider.SearchAsync(query, token);
+ }
if (ActionKeywordMatch(query, Settings.ActionKeyword.PathSearchActionKeyword) ||
ActionKeywordMatch(query, Settings.ActionKeyword.SearchActionKeyword))
@@ -71,8 +79,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
querySearch.Length > 0 &&
!querySearch.IsLocationPathString())
{
- results.UnionWith(await WindowsIndexFilesAndFoldersSearchAsync(query, querySearch, token)
- .ConfigureAwait(false));
+ if (searchResults != null)
+ results.UnionWith(searchResults.Select(search => ResultManager.CreateResult(query, search)));
}
return results.ToList();
@@ -93,7 +101,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
Settings.ActionKeyword.IndexSearchActionKeyword => Settings.IndexSearchKeywordEnabled &&
keyword == Settings.IndexSearchActionKeyword,
Settings.ActionKeyword.QuickAccessActionKeyword => Settings.QuickAccessKeywordEnabled &&
- keyword == Settings.QuickAccessActionKeyword
+ keyword == Settings.QuickAccessActionKeyword
};
}
@@ -126,37 +134,20 @@ namespace Flow.Launcher.Plugin.Explorer.Search
token.ThrowIfCancellationRequested();
- var directoryResult = await TopLevelDirectorySearchBehaviourAsync(WindowsIndexTopLevelFolderSearchAsync,
- DirectoryInfoClassSearch,
- useIndexSearch,
- query,
- locationPath,
- token).ConfigureAwait(false);
+ // var directoryResult = await TopLevelDirectorySearchBehaviourAsync(WindowsIndexTopLevelFolderSearchAsync,
+ // DirectoryInfoClassSearch,
+ // useIndexSearch,
+ // query,
+ // locationPath,
+ // token).ConfigureAwait(false);
token.ThrowIfCancellationRequested();
- results.UnionWith(directoryResult);
+ // results.UnionWith(directoryResult);
return results.ToList();
}
- private async Task> WindowsIndexFileContentSearchAsync(Query query, string querySearchString,
- CancellationToken token)
- {
- var queryConstructor = new QueryConstructor(Settings);
-
- if (string.IsNullOrEmpty(querySearchString))
- return new List();
-
- return await IndexSearch.WindowsIndexSearchAsync(
- querySearchString,
- queryConstructor.CreateQueryHelper,
- queryConstructor.QueryForFileContentSearch,
- Settings.IndexSearchExcludedSubdirectoryPaths,
- query,
- token).ConfigureAwait(false);
- }
-
public bool IsFileContentSearch(string actionKeyword)
{
return actionKeyword == Settings.FileContentSearchActionKeyword;
@@ -181,34 +172,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return await windowsIndexSearch(query, querySearchString, token);
}
- private async Task> WindowsIndexFilesAndFoldersSearchAsync(Query query, string querySearchString,
- CancellationToken token)
- {
- var queryConstructor = new QueryConstructor(Settings);
-
- return await IndexSearch.WindowsIndexSearchAsync(
- querySearchString,
- queryConstructor.CreateQueryHelper,
- queryConstructor.QueryForAllFilesAndFolders,
- Settings.IndexSearchExcludedSubdirectoryPaths,
- query,
- token).ConfigureAwait(false);
- }
-
- private async Task> WindowsIndexTopLevelFolderSearchAsync(Query query, string path,
- CancellationToken token)
- {
- var queryConstructor = new QueryConstructor(Settings);
-
- return await IndexSearch.WindowsIndexSearchAsync(
- path,
- queryConstructor.CreateQueryHelper,
- queryConstructor.QueryForTopLevelDirectorySearch,
- Settings.IndexSearchExcludedSubdirectoryPaths,
- query,
- token).ConfigureAwait(false);
- }
-
private bool UseWindowsIndexForDirectorySearch(string locationPath)
{
var pathToDirectory = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath);
@@ -221,7 +184,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
.StartsWith(x.Path, StringComparison.OrdinalIgnoreCase)))
return false;
- return IndexSearch.PathIsIndexed(pathToDirectory);
+ return WindowsIndex.WindowsIndex.PathIsIndexed(pathToDirectory);
}
}
}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
new file mode 100644
index 000000000..815c6b7b0
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Flow.Launcher.Plugin.Explorer.Search
+{
+ public struct SearchResult
+ {
+ public string FullPath { get; init; }
+ public ResultType Type { get; init; }
+
+ public bool WindowsIndexed { get; init; }
+
+ public bool ShowIndexState { get; init; }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IIndexProvider.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IIndexProvider.cs
new file mode 100644
index 000000000..e42d78f9a
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IIndexProvider.cs
@@ -0,0 +1,13 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
+{
+ public interface IIndexProvider
+ {
+ public ValueTask> SearchAsync(Query query, CancellationToken token);
+ public ValueTask> ContentSearchAsync(Query query, CancellationToken token);
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs
similarity index 71%
rename from Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs
rename to Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs
index 2e842c843..28e9c0e71 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs
@@ -13,16 +13,15 @@ using System.Windows;
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
- internal static class IndexSearch
+ internal static class WindowsIndex
{
// Reserved keywords in oleDB
- private const string reservedStringPattern = @"^[`\@\#\^,\&\/\\\$\%_;\[\]]+$";
+ private const string ReservedStringPattern = @"^[`\@\#\^,\&\/\\\$\%_;\[\]]+$";
- internal static async Task> ExecuteWindowsIndexSearchAsync(string indexQueryString, string connectionString, Query query, CancellationToken token)
+ private static async Task> ExecuteWindowsIndexSearchAsync(string indexQueryString, string connectionString, Query query, CancellationToken token)
{
- var results = new List();
- var fileResults = new List();
+ var results = new List();
try
{
@@ -35,7 +34,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
await using var dataReaderResults = await command.ExecuteReaderAsync(token) as OleDbDataReader;
token.ThrowIfCancellationRequested();
- if (dataReaderResults.HasRows)
+ if (dataReaderResults is { HasRows: true })
{
while (await dataReaderResults.ReadAsync(token))
{
@@ -49,18 +48,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
var path = new Uri(encodedFragmentPath).LocalPath;
- if (dataReaderResults.GetString(2) == "Directory")
+ results.Add(new SearchResult()
{
- results.Add(ResultManager.CreateFolderResult(
- dataReaderResults.GetString(0),
- path,
- path,
- query, 0, true, true));
- }
- else
- {
- fileResults.Add(ResultManager.CreateFileResult(path, query, 0, true, true));
- }
+ FullPath = path,
+ Type = dataReaderResults.GetString(2) == "Directory" ? ResultType.Folder : ResultType.File,
+ WindowsIndexed = true
+ });
}
}
}
@@ -80,13 +73,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
LogException("General error from performing index search", e);
}
- results.AddRange(fileResults);
-
- // Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
- return results;
+ // Initial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
+ return results;
}
- internal async static Task> WindowsIndexSearchAsync(
+ internal static async ValueTask> WindowsIndexSearchAsync(
string searchString,
Func createQueryHelper,
Func constructQuery,
@@ -94,28 +85,15 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
Query query,
CancellationToken token)
{
- var regexMatch = Regex.Match(searchString, reservedStringPattern);
+ var regexMatch = Regex.Match(searchString, ReservedStringPattern);
if (regexMatch.Success)
- return new List();
-
- try
- {
- var constructedQuery = constructQuery(searchString);
+ return new();
- return RemoveResultsInExclusionList(
- await ExecuteWindowsIndexSearchAsync(constructedQuery, createQueryHelper().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();
+ var constructedQuery = constructQuery(searchString);
- return ResultForWindexSearchOff(query.RawQuery);
- }
+ return
+ await ExecuteWindowsIndexSearchAsync(constructedQuery, createQueryHelper().ConnectionString, query, token);
}
private static List RemoveResultsInExclusionList(List results, List exclusionList, CancellationToken token)
@@ -159,7 +137,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
return indexManager.IncludedInCrawlScope(path) > 0;
}
- catch(COMException)
+ catch (COMException)
{
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
return false;
@@ -180,18 +158,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
SearchManager.Settings.WarnWindowsSearchServiceOff = false;
- var pluginsManagerPlugin= api.GetAllPlugins().FirstOrDefault(x => x.Metadata.ID == "9f8f9b14-2518-4907-b211-35ab6290dee7");
+ 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",
+ "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
+ api.GetTranslation("plugin_explorer_alternative_title"),
+ MessageBoxButton.YesNo) == MessageBoxResult.Yes
&& actionKeywordCount == 1)
{
api.ChangeQuery(string.Format("{0} install everything", pluginsManagerPlugin.Metadata.ActionKeywords[0]));
@@ -221,7 +199,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
throw e;
#else
Log.Exception($"|Flow.Launcher.Plugin.Explorer.IndexSearch|{message}", e);
-#endif
+#endif
}
}
-}
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexManager.cs
new file mode 100644
index 000000000..72f5e9cb1
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndexManager.cs
@@ -0,0 +1,70 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
+{
+ public class WindowsIndexManager : IIndexProvider
+ {
+ private Settings Settings { get; }
+ private QueryConstructor QueryConstructor { get; }
+ public WindowsIndexManager(Settings settings)
+ {
+ Settings = settings;
+ QueryConstructor = new QueryConstructor(Settings);
+ }
+
+
+ private async Task> WindowsIndexFileContentSearchAsync(Query query, string querySearchString,
+ CancellationToken token)
+ {
+ if (string.IsNullOrEmpty(querySearchString))
+ return new List();
+
+ return await WindowsIndex.WindowsIndexSearchAsync(
+ querySearchString,
+ QueryConstructor.CreateQueryHelper,
+ QueryConstructor.QueryForFileContentSearch,
+ Settings.IndexSearchExcludedSubdirectoryPaths,
+ query,
+ token).ConfigureAwait(false);
+ }
+
+
+
+ private async Task> WindowsIndexFilesAndFoldersSearchAsync(Query query, string querySearchString,
+ CancellationToken token)
+ {
+ return await WindowsIndex.WindowsIndexSearchAsync(
+ querySearchString,
+ QueryConstructor.CreateQueryHelper,
+ QueryConstructor.QueryForAllFilesAndFolders,
+ Settings.IndexSearchExcludedSubdirectoryPaths,
+ query,
+ token).ConfigureAwait(false);
+ }
+
+
+ private async Task> WindowsIndexTopLevelFolderSearchAsync(Query query, string path,
+ CancellationToken token)
+ {
+ var queryConstructor = new QueryConstructor(Settings);
+
+ return await WindowsIndex.WindowsIndexSearchAsync(
+ path,
+ queryConstructor.CreateQueryHelper,
+ queryConstructor.QueryForTopLevelDirectorySearch,
+ Settings.IndexSearchExcludedSubdirectoryPaths,
+ query,
+ token).ConfigureAwait(false);
+ }
+ public ValueTask> SearchAsync(Query query, CancellationToken token)
+ {
+ return default;
+ }
+ public ValueTask> ContentSearchAsync(Query query, CancellationToken token)
+ {
+ return default;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 351091dfe..f3ce8abc5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -1,7 +1,11 @@
+using Flow.Launcher.Plugin.Everything.Everything;
using Flow.Launcher.Plugin.Explorer.Search;
+using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
+using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace Flow.Launcher.Plugin.Explorer
{
@@ -40,6 +44,43 @@ namespace Flow.Launcher.Plugin.Explorer
public bool WarnWindowsSearchServiceOff { get; set; } = true;
+ private List _indexProviders;
+ public Settings()
+ {
+ _indexProviders = new List()
+ {
+ new EverythingSearchManager(this),
+ new WindowsIndexManager(this)
+ };
+ }
+ public IndexSearchEngineOption IndexSearchEngine { get; set; }
+ public IIndexProvider IndexProvider => _indexProviders[(int)IndexSearchEngine];
+
+ public enum PathTraversalEngineOption
+ {
+ Everything,
+ WindowsIndex,
+ Direct
+ }
+
+ public enum IndexSearchEngineOption
+ {
+ Everything,
+ WindowsIndex
+ }
+ #region Everything Settings
+
+
+ public bool LaunchHidden { get; set; } = false;
+
+ public string EverythingInstalledPath { get; set; }
+
+ public SortOption[] SortOptions { get; set; } = Enum.GetValues();
+
+ public SortOption SortOption { get; set; } = SortOption.NAME_ASCENDING;
+
+ #endregion
+
internal enum ActionKeyword
{
SearchActionKeyword,
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 77ec5457b..e1793ad47 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -9,7 +9,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
public class SettingsViewModel
{
- internal Settings Settings { get; set; }
+ public Settings Settings { get; set; }
internal PluginInitContext Context { get; set; }
@@ -29,7 +29,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
internal void RemoveAccessLinkFromExcludedIndexPaths(AccessLink selectedRow) => Settings.IndexSearchExcludedSubdirectoryPaths.Remove(selectedRow);
- internal void OpenWindowsIndexingOptions()
+ internal static void OpenWindowsIndexingOptions()
{
var psi = new ProcessStartInfo
{
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index a7fa58643..a441c10b5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -6,14 +6,13 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Flow.Launcher.Plugin.Explorer.ViewModels"
xmlns:views="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
+ xmlns:qa="clr-namespace:Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks"
d:DesignHeight="450"
d:DesignWidth="800"
- mc:Ignorable="d">
+ mc:Ignorable="d"
+ d:DataContext="{d:DesignInstance viewModels:SettingsViewModel}">
-
-
-
-
+
@@ -97,8 +96,14 @@
AllowDrop="True"
DragEnter="lbxAccessLinks_DragEnter"
Drop="lbxAccessLinks_Drop"
- ItemTemplate="{StaticResource ListViewTemplateExcludedPaths}" />
+ ItemTemplate="{StaticResource ListViewActionKeywords}" />
+
+
@@ -144,4 +149,4 @@
-
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
index 63c4a8dca..8f60d0178 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
@@ -25,6 +25,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views
public ExplorerSettings(SettingsViewModel viewModel)
{
+ DataContext = viewModel;
+
InitializeComponent();
this.viewModel = viewModel;
@@ -310,7 +312,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
private void btnOpenIndexingOptions_Click(object sender, RoutedEventArgs e)
{
- viewModel.OpenWindowsIndexingOptions();
+ SettingsViewModel.OpenWindowsIndexingOptions();
}
public void SetButtonVisibilityToHidden()