diff --git a/Plugins/Wox.Plugin.Everything/Everything/EverythingAPI.cs b/Plugins/Wox.Plugin.Everything/Everything/EverythingAPI.cs
index 4cf4dbaab1..b9d2098ebd 100644
--- a/Plugins/Wox.Plugin.Everything/Everything/EverythingAPI.cs
+++ b/Plugins/Wox.Plugin.Everything/Everything/EverythingAPI.cs
@@ -2,76 +2,36 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
+using System.Threading;
+using Wox.Infrastructure.Logger;
using Wox.Plugin.Everything.Everything.Exceptions;
namespace Wox.Plugin.Everything.Everything
{
- public sealed class EverythingAPI
+ public interface IEverythingApi
{
- #region DllImport
- [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
- private static extern int Everything_SetSearchW(string lpSearchString);
- [DllImport(Main.DLL)]
- private static extern void Everything_SetMatchPath(bool bEnable);
- [DllImport(Main.DLL)]
- private static extern void Everything_SetMatchCase(bool bEnable);
- [DllImport(Main.DLL)]
- private static extern void Everything_SetMatchWholeWord(bool bEnable);
- [DllImport(Main.DLL)]
- private static extern void Everything_SetRegex(bool bEnable);
- [DllImport(Main.DLL)]
- private static extern void Everything_SetMax(int dwMax);
- [DllImport(Main.DLL)]
- private static extern void Everything_SetOffset(int dwOffset);
+ ///
+ /// Searches the specified key word.
+ ///
+ /// The key word.
+ /// token that allow cancellation
+ /// The offset.
+ /// The max count.
+ ///
+ List Search(string keyWord, CancellationToken token, int offset = 0, int maxCount = 100);
- [DllImport(Main.DLL)]
- private static extern bool Everything_GetMatchPath();
- [DllImport(Main.DLL)]
- private static extern bool Everything_GetMatchCase();
- [DllImport(Main.DLL)]
- private static extern bool Everything_GetMatchWholeWord();
- [DllImport(Main.DLL)]
- private static extern bool Everything_GetRegex();
- [DllImport(Main.DLL)]
- private static extern UInt32 Everything_GetMax();
- [DllImport(Main.DLL)]
- private static extern UInt32 Everything_GetOffset();
- [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
- private static extern string Everything_GetSearchW();
- [DllImport(Main.DLL)]
- private static extern StateCode Everything_GetLastError();
+ void Load(string sdkPath);
+ }
- [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
- private static extern bool Everything_QueryW(bool bWait);
+ public sealed class EverythingApi : IEverythingApi
+ {
+ private const int BufferSize = 4096;
- [DllImport(Main.DLL)]
- private static extern void Everything_SortResultsByPath();
+ private readonly object _syncObject = new object();
+ // cached buffer to remove redundant allocations.
+ private readonly StringBuilder _buffer = new StringBuilder(BufferSize);
- [DllImport(Main.DLL)]
- private static extern int Everything_GetNumFileResults();
- [DllImport(Main.DLL)]
- private static extern int Everything_GetNumFolderResults();
- [DllImport(Main.DLL)]
- private static extern int Everything_GetNumResults();
- [DllImport(Main.DLL)]
- private static extern int Everything_GetTotFileResults();
- [DllImport(Main.DLL)]
- private static extern int Everything_GetTotFolderResults();
- [DllImport(Main.DLL)]
- private static extern int Everything_GetTotResults();
- [DllImport(Main.DLL)]
- private static extern bool Everything_IsVolumeResult(int nIndex);
- [DllImport(Main.DLL)]
- private static extern bool Everything_IsFolderResult(int nIndex);
- [DllImport(Main.DLL)]
- private static extern bool Everything_IsFileResult(int nIndex);
- [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
- private static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);
- [DllImport(Main.DLL)]
- private static extern void Everything_Reset();
- #endregion
-
- enum StateCode
+ public enum StateCode
{
OK,
MemoryError,
@@ -87,15 +47,15 @@ namespace Wox.Plugin.Everything.Everything
/// Gets or sets a value indicating whether [match path].
///
/// true if [match path]; otherwise, false.
- public Boolean MatchPath
+ public bool MatchPath
{
get
{
- return Everything_GetMatchPath();
+ return EverythingApiDllImport.Everything_GetMatchPath();
}
set
{
- Everything_SetMatchPath(value);
+ EverythingApiDllImport.Everything_SetMatchPath(value);
}
}
@@ -103,15 +63,15 @@ namespace Wox.Plugin.Everything.Everything
/// Gets or sets a value indicating whether [match case].
///
/// true if [match case]; otherwise, false.
- public Boolean MatchCase
+ public bool MatchCase
{
get
{
- return Everything_GetMatchCase();
+ return EverythingApiDllImport.Everything_GetMatchCase();
}
set
{
- Everything_SetMatchCase(value);
+ EverythingApiDllImport.Everything_SetMatchCase(value);
}
}
@@ -119,15 +79,15 @@ namespace Wox.Plugin.Everything.Everything
/// Gets or sets a value indicating whether [match whole word].
///
/// true if [match whole word]; otherwise, false.
- public Boolean MatchWholeWord
+ public bool MatchWholeWord
{
get
{
- return Everything_GetMatchWholeWord();
+ return EverythingApiDllImport.Everything_GetMatchWholeWord();
}
set
{
- Everything_SetMatchWholeWord(value);
+ EverythingApiDllImport.Everything_SetMatchWholeWord(value);
}
}
@@ -135,15 +95,15 @@ namespace Wox.Plugin.Everything.Everything
/// Gets or sets a value indicating whether [enable regex].
///
/// true if [enable regex]; otherwise, false.
- public Boolean EnableRegex
+ public bool EnableRegex
{
get
{
- return Everything_GetRegex();
+ return EverythingApiDllImport.Everything_GetRegex();
}
set
{
- Everything_SetRegex(value);
+ EverythingApiDllImport.Everything_SetRegex(value);
}
}
@@ -152,12 +112,91 @@ namespace Wox.Plugin.Everything.Everything
///
public void Reset()
{
- Everything_Reset();
+ lock (_syncObject)
+ {
+ EverythingApiDllImport.Everything_Reset();
+ }
}
- private void no()
+ ///
+ /// 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)
+ /// The offset.
+ /// The max count.
+ ///
+ public List Search(string keyWord, CancellationToken token, int offset = 0, int maxCount = 100)
{
- switch (Everything_GetLastError())
+ 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.Substring(1);
+ }
+
+ EverythingApiDllImport.Everything_SetSearchW(keyWord);
+ EverythingApiDllImport.Everything_SetOffset(offset);
+ EverythingApiDllImport.Everything_SetMax(maxCount);
+
+ if (token.IsCancellationRequested)
+ {
+ return null;
+ }
+
+
+ if (!EverythingApiDllImport.Everything_QueryW(true))
+ {
+ CheckAndThrowExceptionOnError();
+ return null;
+ }
+
+ var results = new List();
+ for (int 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() };
+ if (EverythingApiDllImport.Everything_IsFolderResult(idx))
+ result.Type = ResultType.Folder;
+ else if (EverythingApiDllImport.Everything_IsFileResult(idx))
+ result.Type = ResultType.File;
+
+ results.Add(result);
+ }
+
+ Reset();
+
+ return results;
+ }
+ }
+
+ [DllImport("kernel32.dll")]
+ private static extern int LoadLibrary(string name);
+
+ public void Load(string sdkPath)
+ {
+ LoadLibrary(sdkPath);
+ }
+
+ private static void CheckAndThrowExceptionOnError()
+ {
+ switch (EverythingApiDllImport.Everything_GetLastError())
{
case StateCode.CreateThreadError:
throw new CreateThreadException();
@@ -175,71 +214,5 @@ namespace Wox.Plugin.Everything.Everything
throw new RegisterClassExException();
}
}
-
- ///
- /// Searches the specified key word.
- ///
- /// The key word.
- /// The offset.
- /// The max count.
- ///
- public IEnumerable Search(string keyWord, int offset = 0, int maxCount = 100)
- {
- if (string.IsNullOrEmpty(keyWord))
- throw new ArgumentNullException("keyWord");
-
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset");
-
- if (maxCount < 0)
- throw new ArgumentOutOfRangeException("maxCount");
-
- if (keyWord.StartsWith("@"))
- {
- Everything_SetRegex(true);
- keyWord = keyWord.Substring(1);
- }
- Everything_SetSearchW(keyWord);
- Everything_SetOffset(offset);
- Everything_SetMax(maxCount);
-
-
- if (!Everything_QueryW(true))
- {
- switch (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();
- }
- yield break;
- }
-
- const int bufferSize = 4096;
- StringBuilder buffer = new StringBuilder(bufferSize);
- for (int idx = 0; idx < Everything_GetNumResults(); ++idx)
- {
- Everything_GetResultFullPathNameW(idx, buffer, bufferSize);
-
- var result = new SearchResult { FullPath = buffer.ToString() };
- if (Everything_IsFolderResult(idx))
- result.Type = ResultType.Folder;
- else if (Everything_IsFileResult(idx))
- result.Type = ResultType.File;
-
- yield return result;
- }
- }
}
}
diff --git a/Plugins/Wox.Plugin.Everything/Everything/EverythingApiDllImport.cs b/Plugins/Wox.Plugin.Everything/Everything/EverythingApiDllImport.cs
new file mode 100644
index 0000000000..6c056a0f57
--- /dev/null
+++ b/Plugins/Wox.Plugin.Everything/Everything/EverythingApiDllImport.cs
@@ -0,0 +1,92 @@
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Wox.Plugin.Everything.Everything
+{
+ public sealed class EverythingApiDllImport
+ {
+ [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
+ internal static extern int Everything_SetSearchW(string lpSearchString);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SetMatchPath(bool bEnable);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SetMatchCase(bool bEnable);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SetMatchWholeWord(bool bEnable);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SetRegex(bool bEnable);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SetMax(int dwMax);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SetOffset(int dwOffset);
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_GetMatchPath();
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_GetMatchCase();
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_GetMatchWholeWord();
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_GetRegex();
+
+ [DllImport(Main.DLL)]
+ internal static extern uint Everything_GetMax();
+
+ [DllImport(Main.DLL)]
+ internal static extern uint Everything_GetOffset();
+
+ [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
+ internal static extern string Everything_GetSearchW();
+
+ [DllImport(Main.DLL)]
+ internal static extern EverythingApi.StateCode Everything_GetLastError();
+
+ [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
+ internal static extern bool Everything_QueryW(bool bWait);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_SortResultsByPath();
+
+ [DllImport(Main.DLL)]
+ internal static extern int Everything_GetNumFileResults();
+
+ [DllImport(Main.DLL)]
+ internal static extern int Everything_GetNumFolderResults();
+
+ [DllImport(Main.DLL)]
+ internal static extern int Everything_GetNumResults();
+
+ [DllImport(Main.DLL)]
+ internal static extern int Everything_GetTotFileResults();
+
+ [DllImport(Main.DLL)]
+ internal static extern int Everything_GetTotFolderResults();
+
+ [DllImport(Main.DLL)]
+ internal static extern int Everything_GetTotResults();
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_IsVolumeResult(int nIndex);
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_IsFolderResult(int nIndex);
+
+ [DllImport(Main.DLL)]
+ internal static extern bool Everything_IsFileResult(int nIndex);
+
+ [DllImport(Main.DLL, CharSet = CharSet.Unicode)]
+ internal static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);
+
+ [DllImport(Main.DLL)]
+ internal static extern void Everything_Reset();
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Wox.Plugin.Everything/IEverythingDllLoader.cs b/Plugins/Wox.Plugin.Everything/IEverythingDllLoader.cs
new file mode 100644
index 0000000000..e78c4b1b88
--- /dev/null
+++ b/Plugins/Wox.Plugin.Everything/IEverythingDllLoader.cs
@@ -0,0 +1,37 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using Wox.Infrastructure;
+
+namespace Wox.Plugin.Everything
+{
+ public interface IEverythingDllLoader
+ {
+ void Load(PluginInitContext context);
+ }
+
+ public class EverythingDllLoader : IEverythingDllLoader
+ {
+
+
+ public void Load(PluginInitContext context)
+ {
+ //var pluginDirectory = context.CurrentPluginMetadata.PluginDirectory;
+ //const string sdk = "EverythingSDK";
+ //var bundledSDKDirectory = Path.Combine(pluginDirectory, sdk, CpuType());
+ //var sdkDirectory = Path.Combine(_storage.DirectoryPath, sdk, CpuType());
+ //Helper.ValidateDataDirectory(bundledSDKDirectory, sdkDirectory);
+
+ //var sdkPath = Path.Combine(sdkDirectory, DLL);
+ //Constant.EverythingSDKPath = sdkPath;
+ //LoadLibrary(sdkPath);
+ }
+
+
+
+ private static string CpuType()
+ {
+ return Environment.Is64BitOperatingSystem ? "x64" : "x86";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs
index 4188f89dda..6c4e3f20df 100644
--- a/Plugins/Wox.Plugin.Everything/Main.cs
+++ b/Plugins/Wox.Plugin.Everything/Main.cs
@@ -3,11 +3,12 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
-using System.Linq;
using System.Runtime.InteropServices;
+using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Wox.Infrastructure;
+using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage;
using Wox.Plugin.Everything.Everything;
@@ -15,14 +16,16 @@ namespace Wox.Plugin.Everything
{
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
{
- private readonly EverythingAPI _api = new EverythingAPI();
-
public const string DLL = "Everything.dll";
+ private readonly IEverythingApi _api = new EverythingApi();
+
+
private PluginInitContext _context;
private Settings _settings;
private PluginJsonStorage _storage;
+ private CancellationTokenSource _cancellationTokenSource;
public void Save()
{
@@ -31,55 +34,24 @@ namespace Wox.Plugin.Everything
public List Query(Query query)
{
+ _cancellationTokenSource?.Cancel(); // cancel if already exist
+ var cts = _cancellationTokenSource = new CancellationTokenSource();
var results = new List();
if (!string.IsNullOrEmpty(query.Search))
{
var keyword = query.Search;
- if (_settings.MaxSearchCount <= 0)
- {
- _settings.MaxSearchCount = 50;
- }
-
+
try
{
- var searchList = _api.Search(keyword, maxCount: _settings.MaxSearchCount).ToList();
- foreach (var s in searchList)
+ var searchList = _api.Search(keyword, cts.Token, maxCount: _settings.MaxSearchCount);
+ if (searchList == null)
{
- var path = s.FullPath;
+ return results;
+ }
- string workingDir = null;
- if (_settings.UseLocationAsWorkingDir)
- workingDir = Path.GetDirectoryName(path);
-
- Result r = new Result();
- r.Title = Path.GetFileName(path);
- r.SubTitle = path;
- r.IcoPath = path;
- r.TitleHighlightData = StringMatcher.FuzzySearch(keyword, Path.GetFileName(path)).MatchData;
- r.Action = c =>
- {
- bool hide;
- try
- {
- Process.Start(new ProcessStartInfo
- {
- FileName = path,
- UseShellExecute = true,
- WorkingDirectory = workingDir
- });
- hide = true;
- }
- catch (Win32Exception)
- {
- var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
- var message = "Can't open this file";
- _context.API.ShowMsg(name, message, string.Empty);
- hide = false;
- }
- return hide;
- };
- r.ContextData = s;
- r.SubTitleHighlightData = StringMatcher.FuzzySearch(keyword, path).MatchData;
+ foreach (var searchResult in searchList)
+ {
+ var r = CreateResult(keyword, searchResult);
results.Add(r);
}
}
@@ -93,6 +65,7 @@ namespace Wox.Plugin.Everything
}
catch (Exception e)
{
+ Log.Exception("EverythingPlugin", "Query Error", e);
results.Add(new Result
{
Title = _context.API.GetTranslation("wox_plugin_everything_query_error"),
@@ -108,13 +81,51 @@ namespace Wox.Plugin.Everything
}
}
- _api.Reset();
-
return results;
}
- [DllImport("kernel32.dll")]
- private static extern int LoadLibrary(string name);
+ private Result CreateResult(string keyword, SearchResult searchResult)
+ {
+ var path = searchResult.FullPath;
+
+ string workingDir = null;
+ if (_settings.UseLocationAsWorkingDir)
+ workingDir = Path.GetDirectoryName(path);
+
+ var r = new Result
+ {
+ Title = Path.GetFileName(path),
+ SubTitle = path,
+ IcoPath = path,
+ TitleHighlightData = StringMatcher.FuzzySearch(keyword, Path.GetFileName(path)).MatchData,
+ Action = c =>
+ {
+ bool hide;
+ try
+ {
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = path, UseShellExecute = true, WorkingDirectory = workingDir
+ });
+ hide = true;
+ }
+ catch (Win32Exception)
+ {
+ var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
+ var message = "Can't open this file";
+ _context.API.ShowMsg(name, message, string.Empty);
+ hide = false;
+ }
+
+ return hide;
+ },
+ ContextData = searchResult,
+ SubTitleHighlightData = StringMatcher.FuzzySearch(keyword, path).MatchData
+ };
+ return r;
+ }
+
+
private List GetDefaultContextMenu()
{
@@ -149,6 +160,10 @@ namespace Wox.Plugin.Everything
_context = context;
_storage = new PluginJsonStorage();
_settings = _storage.Load();
+ if (_settings.MaxSearchCount <= 0)
+ {
+ _settings.MaxSearchCount = Settings.DefaultMaxSearchCount;
+ }
var pluginDirectory = context.CurrentPluginMetadata.PluginDirectory;
const string sdk = "EverythingSDK";
@@ -158,7 +173,7 @@ namespace Wox.Plugin.Everything
var sdkPath = Path.Combine(sdkDirectory, DLL);
Constant.EverythingSDKPath = sdkPath;
- LoadLibrary(sdkPath);
+ _api.Load(sdkPath);
}
private static string CpuType()
diff --git a/Plugins/Wox.Plugin.Everything/Settings.cs b/Plugins/Wox.Plugin.Everything/Settings.cs
index a2d7069fed..9fb5ac89bb 100644
--- a/Plugins/Wox.Plugin.Everything/Settings.cs
+++ b/Plugins/Wox.Plugin.Everything/Settings.cs
@@ -7,11 +7,13 @@ namespace Wox.Plugin.Everything
{
public class Settings
{
+ public const int DefaultMaxSearchCount = 50;
+
public string EditorPath { get; set; } = "";
public List ContextMenus = new List();
- public int MaxSearchCount { get; set; } = 100;
+ public int MaxSearchCount { get; set; } = DefaultMaxSearchCount;
public bool UseLocationAsWorkingDir { get; set; } = false;
}
diff --git a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj
index 3c84f90b89..627c5a325e 100644
--- a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj
+++ b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj
@@ -61,6 +61,7 @@
EverythingSettings.xaml
+
@@ -71,6 +72,7 @@
+
diff --git a/Wox.Infrastructure/Helper.cs b/Wox.Infrastructure/Helper.cs
index 6d0b30f5de..dc31bd70d7 100644
--- a/Wox.Infrastructure/Helper.cs
+++ b/Wox.Infrastructure/Helper.cs
@@ -32,7 +32,6 @@ namespace Wox.Infrastructure
public static void ValidateDataDirectory(string bundledDataDirectory, string dataDirectory)
{
-
if (!Directory.Exists(dataDirectory))
{
Directory.CreateDirectory(dataDirectory);
diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs
index e75f046813..0fc1e8c95e 100644
--- a/Wox/App.xaml.cs
+++ b/Wox/App.xaml.cs
@@ -148,10 +148,6 @@ namespace Wox
private static void RegisterAppDomainExceptions()
{
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
- AppDomain.CurrentDomain.FirstChanceException += (_, e) =>
- {
- Log.Exception("|App.RegisterAppDomainExceptions|First Chance Exception:", e.Exception);
- };
}
public void Dispose()