diff --git a/Plugins/Wox.Plugin.BrowserBookmark/Commands/Bookmarks.cs b/Plugins/Wox.Plugin.BrowserBookmark/Commands/Bookmarks.cs
index 778e0ee65..049b8f166 100644
--- a/Plugins/Wox.Plugin.BrowserBookmark/Commands/Bookmarks.cs
+++ b/Plugins/Wox.Plugin.BrowserBookmark/Commands/Bookmarks.cs
@@ -8,9 +8,9 @@ namespace Wox.Plugin.BrowserBookmark.Commands
{
internal static bool MatchProgram(Bookmark bookmark, string queryString)
{
- if (StringMatcher.FuzzySearch(queryString, bookmark.Name, new MatchOption()).IsSearchPrecisionScoreMet()) return true;
- if (StringMatcher.FuzzySearch(queryString, bookmark.PinyinName, new MatchOption()).IsSearchPrecisionScoreMet()) return true;
- if (StringMatcher.FuzzySearch(queryString, bookmark.Url, new MatchOption()).IsSearchPrecisionScoreMet()) return true;
+ if (StringMatcher.FuzzySearch(queryString, bookmark.Name).IsSearchPrecisionScoreMet()) return true;
+ if (StringMatcher.FuzzySearch(queryString, bookmark.PinyinName).IsSearchPrecisionScoreMet()) return true;
+ if (StringMatcher.FuzzySearch(queryString, bookmark.Url).IsSearchPrecisionScoreMet()) return true;
return false;
}
diff --git a/Plugins/Wox.Plugin.Program/Logger/ProgramLogger.cs b/Plugins/Wox.Plugin.Program/Logger/ProgramLogger.cs
new file mode 100644
index 000000000..c8a104b10
--- /dev/null
+++ b/Plugins/Wox.Plugin.Program/Logger/ProgramLogger.cs
@@ -0,0 +1,122 @@
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Security;
+using Wox.Infrastructure;
+
+namespace Wox.Plugin.Program.Logger
+{
+ ///
+ /// The Program plugin has seen many issues recorded in the Wox repo related to various loading of Windows programs.
+ /// This is a dedicated logger for this Program plugin with the aim to output a more friendlier message and clearer
+ /// log that will allow debugging to be quicker and easier.
+ ///
+ internal static class ProgramLogger
+ {
+ public const string DirectoryName = "Logs";
+
+ static ProgramLogger()
+ {
+ var path = Path.Combine(Constant.DataDirectory, DirectoryName, Constant.Version);
+ if (!Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+
+ var configuration = new LoggingConfiguration();
+ var target = new FileTarget();
+ configuration.AddTarget("file", target);
+ target.FileName = path.Replace(@"\", "/") + "/${shortdate}.txt";
+#if DEBUG
+ var rule = new LoggingRule("*", LogLevel.Debug, target);
+#else
+ var rule = new LoggingRule("*", LogLevel.Error, target);
+#endif
+ configuration.LoggingRules.Add(rule);
+ LogManager.Configuration = configuration;
+ }
+
+ ///
+ /// Please follow exception format: |class name|calling method name|loading program path|user friendly message that explains the error
+ /// => Example: |Win32|LnkProgram|c:\..\chrome.exe|Permission denied on directory, but Wox should continue
+ ///
+ [MethodImpl(MethodImplOptions.Synchronized)]
+ internal static void LogException(string message, Exception e)
+ {
+ //Index 0 is always empty.
+ var parts = message.Split('|');
+ var classname = parts[1];
+ var callingMethodName = parts[2];
+ var loadingProgramPath = parts[3];
+ var interpretationMessage = parts[4];
+
+ Debug.WriteLine($"ERROR{message}");
+
+ var logger = LogManager.GetLogger("");
+
+ var innerExceptionNumber = 1;
+
+ var possibleResolution = "Not yet known";
+ var errorStatus = "UNKNOWN";
+
+ logger.Error("------------- BEGIN Wox.Plugin.Program exception -------------");
+
+ do
+ {
+ if (IsKnownWinProgramError(e, callingMethodName) || IsKnownUWPProgramError(e, callingMethodName))
+ {
+ possibleResolution = "Can be ignored and Wox should still continue, however the program may not be loaded";
+ errorStatus = "KNOWN";
+ }
+
+ var calledMethod = e.TargetSite != null ? e.TargetSite.ToString() : e.StackTrace;
+
+ calledMethod = string.IsNullOrEmpty(calledMethod) ? "Not available" : calledMethod;
+
+ logger.Error($"\nException full name: {e.GetType().FullName}"
+ + $"\nError status: {errorStatus}"
+ + $"\nClass name: {classname}"
+ + $"\nCalling method: {callingMethodName}"
+ + $"\nProgram path: {loadingProgramPath}"
+ + $"\nInnerException number: {innerExceptionNumber}"
+ + $"\nException message: {e.Message}"
+ + $"\nException error type: HResult {e.HResult}"
+ + $"\nException thrown in called method: {calledMethod}"
+ + $"\nPossible interpretation of the error: {interpretationMessage}"
+ + $"\nPossible resolution: {possibleResolution}");
+
+ innerExceptionNumber++;
+ e = e.InnerException;
+ } while (e != null);
+
+ logger.Error("------------- END Wox.Plugin.Program exception -------------");
+ }
+
+ private static bool IsKnownWinProgramError(Exception e, string callingMethodName)
+ {
+ if (e.TargetSite?.Name == "GetDescription" && callingMethodName == "LnkProgram")
+ return true;
+
+ if (e is SecurityException || e is UnauthorizedAccessException || e is DirectoryNotFoundException)
+ return true;
+
+ return false;
+ }
+
+ private static bool IsKnownUWPProgramError(Exception e, string callingMethodName)
+ {
+ if (((e.HResult == -2147024774 || e.HResult == -2147009769) && callingMethodName == "ResourceFromPri")
+ || (e.HResult == -2147024894 && callingMethodName == "LogoPathFromUri"))
+ return true;
+
+ if (callingMethodName == "XmlNamespaces")
+ return true;
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Wox.Plugin.Program/Programs/UWP.cs b/Plugins/Wox.Plugin.Program/Programs/UWP.cs
index 9a7bcccb9..360b74431 100644
--- a/Plugins/Wox.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Wox.Plugin.Program/Programs/UWP.cs
@@ -15,7 +15,7 @@ using Windows.Management.Deployment;
using AppxPackaing;
using Shell;
using Wox.Infrastructure;
-using Wox.Infrastructure.Logger;
+using Wox.Plugin.Program.Logger;
using IStream = AppxPackaing.IStream;
using Rect = System.Windows.Rect;
@@ -84,7 +84,8 @@ namespace Wox.Plugin.Program.Programs
else
{
var e = Marshal.GetExceptionForHR((int)hResult);
- Log.Exception($"|UWP.InitializeAppInfo|SHCreateStreamOnFileEx on path <{path}> failed with HResult <{hResult}> and location <{Location}>.", e);
+ ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" +
+ "|Error caused while trying to get the details of the UWP program", e);
}
}
@@ -108,7 +109,9 @@ namespace Wox.Plugin.Program.Programs
}
else
{
- Log.Error($"|UWP.XmlNamespaces|can't find namespaces for <{path}>");
+ ProgramLogger.LogException($"|UWP|XmlNamespaces|{path}" +
+ $"|Error occured while trying to get the XML from {path}", new ArgumentNullException());
+
return new string[] { };
}
}
@@ -131,15 +134,13 @@ namespace Wox.Plugin.Program.Programs
}
}
- Log.Error($"|UWP.InitPackageVersion| Unknown Appmanifest version UWP <{FullName}> with location <{Location}>.");
+ ProgramLogger.LogException($"|UWP|XmlNamespaces|{Location}" +
+ "|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version "
+ + $"{FullName} from location {Location} is returned.", new FormatException());
+
Version = PackageVersion.Unknown;
}
-
-
-
-
-
public static Application[] All()
{
var windows10 = new Version(10, 0);
@@ -153,11 +154,20 @@ namespace Wox.Plugin.Program.Programs
{
u = new UWP(p);
}
+#if !DEBUG
catch (Exception e)
{
- Log.Exception($"|UWP.All|Can't convert Package to UWP for <{p.Id.FullName}>:", e);
+ ProgramLogger.LogException("|UWP|All|An unexpected error occured and "
+ + $"unable to convert Package to UWP for {p.Id.FullName}", e);
return new Application[] { };
}
+#endif
+#if DEBUG //make developer aware and implement handling
+ catch(Exception)
+ {
+ throw;
+ }
+#endif
return u.Apps;
}).ToArray();
@@ -186,18 +196,12 @@ namespace Wox.Plugin.Program.Programs
ps = ps.Where(p =>
{
bool valid;
- try
- {
- var f = p.IsFramework;
- var d = p.IsDevelopmentMode;
- var path = p.InstalledLocation.Path;
- valid = !f && !d && !string.IsNullOrEmpty(path);
- }
- catch (Exception e)
- {
- Log.Exception($"|UWP.CurrentUserPackages|Can't get package info for <{p.Id.FullName}>", e);
- valid = false;
- }
+
+ var f = p.IsFramework;
+ var d = p.IsDevelopmentMode;
+ var path = p.InstalledLocation.Path;
+ valid = !f && !d && !string.IsNullOrEmpty(path);
+
return valid;
});
return ps;
@@ -382,7 +386,8 @@ namespace Wox.Plugin.Program.Programs
}
else
{
- Log.Error($"|UWP.ResourceFromPri|Can't load null or empty result pri <{source}> with uwp location <{Package.Location}>.");
+ ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Can't load null or empty result "
+ + $"pri {source} in uwp location {Package.Location}", new NullReferenceException());
return string.Empty;
}
}
@@ -395,7 +400,7 @@ namespace Wox.Plugin.Program.Programs
// Microsoft.MicrosoftOfficeHub_17.7608.23501.0_x64__8wekyb3d8bbwe: ms-resource://Microsoft.MicrosoftOfficeHub/officehubintl/AppManifest_GetOffice_Description
// Microsoft.BingFoodAndDrink_3.0.4.336_x64__8wekyb3d8bbwe: ms-resource:AppDescription
var e = Marshal.GetExceptionForHR((int)hResult);
- Log.Exception($"|UWP.ResourceFromPri|Load pri failed <{source}> with HResult <{hResult}> and location <{Package.Location}>.", e);
+ ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Load pri failed {source} with HResult {hResult} and location {Package.Location}", e);
return string.Empty;
}
}
@@ -474,13 +479,16 @@ namespace Wox.Plugin.Program.Programs
}
else
{
- Log.Error($"|UWP.LogoPathFromUri| <{UserModelId}> can't find logo uri for <{uri}>, Package location <{Package.Location}>.");
+ ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
+ $"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException());
return string.Empty;
}
}
else
{
- Log.Error($"|UWP.LogoPathFromUri| <{UserModelId}> cantains can't find extension for <{uri}> Package location <{Package.Location}>.");
+ ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
+ $"|Unable to find extension from {uri} for {UserModelId} " +
+ $"in package location {Package.Location}", new FileNotFoundException());
return string.Empty;
}
}
@@ -506,7 +514,9 @@ namespace Wox.Plugin.Program.Programs
}
else
{
- Log.Error($"|UWP.ImageFromPath|Can't get logo for <{UserModelId}> with path <{path}> and location <{Package.Location}>");
+ ProgramLogger.LogException($"|UWP|ImageFromPath|{path}" +
+ $"|Unable to get logo for {UserModelId} from {path} and" +
+ $" located in {Package.Location}", new FileNotFoundException());
return new BitmapImage(new Uri(Constant.ErrorIcon));
}
}
@@ -553,7 +563,10 @@ namespace Wox.Plugin.Program.Programs
}
else
{
- Log.Error($"|UWP.PlatedImage| Can't convert background string <{BackgroundColor}> to color for <{Package.Location}>.");
+ ProgramLogger.LogException($"|UWP|PlatedImage|{Package.Location}" +
+ $"|Unable to convert background string {BackgroundColor} " +
+ $"to color for {Package.Location}", new InvalidOperationException());
+
return new BitmapImage(new Uri(Constant.ErrorIcon));
}
}
diff --git a/Plugins/Wox.Plugin.Program/Programs/Win32.cs b/Plugins/Wox.Plugin.Program/Programs/Win32.cs
index 250d7d4f7..dc11a5665 100644
--- a/Plugins/Wox.Plugin.Program/Programs/Win32.cs
+++ b/Plugins/Wox.Plugin.Program/Programs/Win32.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -10,7 +9,7 @@ using System.Text;
using Microsoft.Win32;
using Shell;
using Wox.Infrastructure;
-using Wox.Infrastructure.Logger;
+using Wox.Plugin.Program.Logger;
namespace Wox.Plugin.Program.Programs
{
@@ -125,18 +124,28 @@ namespace Wox.Plugin.Program.Programs
private static Win32 Win32Program(string path)
{
- var p = new Win32
+ try
{
- Name = Path.GetFileNameWithoutExtension(path),
- IcoPath = path,
- FullPath = path,
- UniqueIdentifier = path,
- ParentDirectory = Directory.GetParent(path).FullName,
- Description = string.Empty,
- Valid = true,
- Enabled = true
- };
- return p;
+ var p = new Win32
+ {
+ Name = Path.GetFileNameWithoutExtension(path),
+ IcoPath = path,
+ FullPath = path,
+ UniqueIdentifier = path,
+ ParentDirectory = Directory.GetParent(path).FullName,
+ Description = string.Empty,
+ Valid = true,
+ Enabled = true
+ };
+ return p;
+ }
+ catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
+ {
+ ProgramLogger.LogException($"|Win32|Win32Program|{path}" +
+ $"|Permission denied when trying to load the program from {path}", e);
+
+ return new Win32() { Valid = false, Enabled = false };
+ }
}
private static Win32 LnkProgram(string path)
@@ -184,27 +193,43 @@ namespace Wox.Plugin.Program.Programs
catch (COMException e)
{
// C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\MiracastView.lnk always cause exception
- Log.Exception($"|Win32.LnkProgram|COMException when parsing shortcut <{path}> with HResult <{e.HResult}>", e);
+ ProgramLogger.LogException($"|Win32|LnkProgram|{path}"+
+ "|Error caused likely due to trying to get the description of the program", e);
+
program.Valid = false;
return program;
}
+#if !DEBUG //Only do a catch all in production. This is so make developer aware of any unhandled exception and add the exception handling in.
catch (Exception e)
{
- Log.Exception($"|Win32.LnkProgram|Exception when parsing shortcut <{path}>", e);
+ ProgramLogger.LogException($"|Win32|LnkProgram|{path}" +
+ "|An unexpected error occurred in the calling method LnkProgram", e);
+
program.Valid = false;
return program;
}
+#endif
}
private static Win32 ExeProgram(string path)
{
- var program = Win32Program(path);
- var info = FileVersionInfo.GetVersionInfo(path);
- if (!string.IsNullOrEmpty(info.FileDescription))
+ try
{
- program.Description = info.FileDescription;
+ var program = Win32Program(path);
+ var info = FileVersionInfo.GetVersionInfo(path);
+ if (!string.IsNullOrEmpty(info.FileDescription))
+ {
+ program.Description = info.FileDescription;
+ }
+ return program;
+ }
+ catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
+ {
+ ProgramLogger.LogException($"|Win32|ExeProgram|{path}" +
+ $"|Permission denied when trying to load the program from {path}", e);
+
+ return new Win32() { Valid = false, Enabled = false };
}
- return program;
}
private static IEnumerable ProgramPaths(string directory, string[] suffixes)
@@ -227,14 +252,15 @@ namespace Wox.Plugin.Program.Programs
}
catch (DirectoryNotFoundException e)
{
- Log.Exception($"|Program.Win32.ProgramPaths|skip directory(<{currentDirectory}>)", e);
- continue;
+ ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" +
+ "|The directory trying to load the program from does not exist", e);
}
}
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
- Log.Exception($"|Program.Win32.ProgramPaths|Don't have permission on <{currentDirectory}>", e);
+ ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" +
+ $"|Permission denied when trying to load programs from {currentDirectory}", e);
}
try
@@ -246,7 +272,8 @@ namespace Wox.Plugin.Program.Programs
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
- Log.Exception($"|Program.Win32.ProgramPaths|Don't have permission on <{currentDirectory}>", e);
+ ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" +
+ $"|Permission denied when trying to load programs from {currentDirectory}", e);
}
} while (folderQueue.Any());
return files;
@@ -348,21 +375,30 @@ namespace Wox.Plugin.Program.Programs
private static string GetProgramPathFromRegistrySubKeys(RegistryKey root, string subkey)
{
var path = string.Empty;
-
- using (var key = root.OpenSubKey(subkey))
+ try
{
- if (key == null)
+ using (var key = root.OpenSubKey(subkey))
+ {
+ if (key == null)
+ return string.Empty;
+
+ var defaultValue = string.Empty;
+ path = key.GetValue(defaultValue) as string;
+ }
+
+ if (string.IsNullOrEmpty(path))
return string.Empty;
- var defaultValue = string.Empty;
- path = key.GetValue(defaultValue) as string;
+ // fix path like this: ""\"C:\\folder\\executable.exe\""
+ return path = path.Trim('"', ' ');
}
+ catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
+ {
+ ProgramLogger.LogException($"|Win32|GetProgramPathFromRegistrySubKeys|{path}" +
+ $"|Permission denied when trying to load the program from {path}", e);
- if (string.IsNullOrEmpty(path))
return string.Empty;
-
- // fix path like this: ""\"C:\\folder\\executable.exe\""
- return path = path.Trim('"', ' ');
+ }
}
private static Win32 GetProgramFromPath(string path)
@@ -383,23 +419,41 @@ namespace Wox.Plugin.Program.Programs
public static Win32[] All(Settings settings)
{
- var programs = new List().AsParallel();
-
- var unregistered = UnregisteredPrograms(settings.ProgramSources, settings.ProgramSuffixes);
- programs = programs.Concat(unregistered);
- if (settings.EnableRegistrySource)
+ try
{
- var appPaths = AppPathsPrograms(settings.ProgramSuffixes);
- programs = programs.Concat(appPaths);
- }
+ var programs = new List().AsParallel();
- if (settings.EnableStartMenuSource)
+ var unregistered = UnregisteredPrograms(settings.ProgramSources, settings.ProgramSuffixes);
+ programs = programs.Concat(unregistered);
+ if (settings.EnableRegistrySource)
+ {
+ var appPaths = AppPathsPrograms(settings.ProgramSuffixes);
+ programs = programs.Concat(appPaths);
+ }
+
+ if (settings.EnableStartMenuSource)
+ {
+ var startMenu = StartMenuPrograms(settings.ProgramSuffixes);
+ programs = programs.Concat(startMenu);
+ }
+
+ return programs.ToArray();
+ }
+#if DEBUG //This is to make developer aware of any unhandled exception and add in handling.
+ catch (Exception e)
{
- var startMenu = StartMenuPrograms(settings.ProgramSuffixes);
- programs = programs.Concat(startMenu);
+ throw e;
}
+#endif
- return programs.ToArray();
+#if !DEBUG //Only do a catch all in production.
+ catch (Exception e)
+ {
+ ProgramLogger.LogException("|Win32|All|Not available|An unexpected error occurred", e);
+
+ return new Win32[0];
+ }
+#endif
}
}
}
diff --git a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj
index 58b93f8c6..850f972ca 100644
--- a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj
+++ b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj
@@ -49,6 +49,9 @@
..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
True
+
+ ..\..\packages\NLog.4.2.0\lib\net45\NLog.dll
+
@@ -71,6 +74,7 @@
AddProgramSource.xaml
+
diff --git a/Plugins/Wox.Plugin.Program/packages.config b/Plugins/Wox.Plugin.Program/packages.config
index 79ae18b0f..01771679c 100644
--- a/Plugins/Wox.Plugin.Program/packages.config
+++ b/Plugins/Wox.Plugin.Program/packages.config
@@ -2,6 +2,7 @@
+
\ No newline at end of file
diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs
index e42cf02e8..d6806e5cb 100644
--- a/Wox.Core/Plugin/PluginManager.cs
+++ b/Wox.Core/Plugin/PluginManager.cs
@@ -135,7 +135,7 @@ namespace Wox.Core.Plugin
var rawQuery = string.Join(Query.TermSeperater, terms);
var actionKeyword = string.Empty;
var search = rawQuery;
- List actionParameters = terms.ToList();
+ var actionParameters = terms.ToList();
if (terms.Length == 0) return null;
if (NonGlobalPlugins.ContainsKey(terms[0]) &&
!Settings.Plugins[NonGlobalPlugins[terms[0]].Metadata.ID].Disabled)
diff --git a/Wox.Infrastructure/FuzzyMatcher.cs b/Wox.Infrastructure/FuzzyMatcher.cs
index cb1e735f5..ddd26be83 100644
--- a/Wox.Infrastructure/FuzzyMatcher.cs
+++ b/Wox.Infrastructure/FuzzyMatcher.cs
@@ -16,7 +16,7 @@ namespace Wox.Infrastructure
public static FuzzyMatcher Create(string query)
{
- return new FuzzyMatcher(query, new MatchOption());
+ return new FuzzyMatcher(query, StringMatcher.DefaultMatchOption);
}
public static FuzzyMatcher Create(string query, MatchOption opt)
diff --git a/Wox.Infrastructure/StringMatcher.cs b/Wox.Infrastructure/StringMatcher.cs
index 0f2657a49..9c49b4119 100644
--- a/Wox.Infrastructure/StringMatcher.cs
+++ b/Wox.Infrastructure/StringMatcher.cs
@@ -8,6 +8,8 @@ namespace Wox.Infrastructure
{
public static class StringMatcher
{
+ public static MatchOption DefaultMatchOption = new MatchOption();
+
public static string UserSettingSearchPrecision { get; set; }
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
@@ -15,7 +17,7 @@ namespace Wox.Infrastructure
{
if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(target))
{
- return FuzzySearch(target, source, new MatchOption()).Score;
+ return FuzzySearch(target, source, DefaultMatchOption).Score;
}
else
{
@@ -26,12 +28,12 @@ namespace Wox.Infrastructure
[Obsolete("This method is obsolete and should not be used. Please use the static function StringMatcher.FuzzySearch")]
public static bool IsMatch(string source, string target)
{
- return FuzzySearch(target, source, new MatchOption()).Score > 0;
+ return FuzzySearch(target, source, DefaultMatchOption).Score > 0;
}
public static MatchResult FuzzySearch(string query, string stringToCompare)
{
- return FuzzySearch(query, stringToCompare, new MatchOption());
+ return FuzzySearch(query, stringToCompare, DefaultMatchOption);
}
///
@@ -41,7 +43,7 @@ namespace Wox.Infrastructure
{
if (string.IsNullOrEmpty(stringToCompare) || string.IsNullOrEmpty(query)) return new MatchResult { Success = false };
- query.Trim();
+ query = query.Trim();
var len = stringToCompare.Length;
var compareString = opt.IgnoreCase ? stringToCompare.ToLower() : stringToCompare;
@@ -98,9 +100,9 @@ namespace Wox.Infrastructure
var score = 100 * (query.Length + 1) / ((1 + firstIndex) + (matchLen + 1));
//a match with less characters assigning more weights
if (stringToCompare.Length - query.Length < 5)
- score = score + 20;
+ score += 20;
else if (stringToCompare.Length - query.Length < 10)
- score = score + 10;
+ score += 10;
return score;
}
@@ -139,10 +141,10 @@ namespace Wox.Infrastructure
{
var combination = Alphabet.PinyinComination(source);
var pinyinScore = combination
- .Select(pinyin => FuzzySearch(target, string.Join("", pinyin), new MatchOption()).Score)
+ .Select(pinyin => FuzzySearch(target, string.Join("", pinyin)).Score)
.Max();
var acronymScore = combination.Select(Alphabet.Acronym)
- .Select(pinyin => FuzzySearch(target, pinyin, new MatchOption()).Score)
+ .Select(pinyin => FuzzySearch(target, pinyin).Score)
.Max();
var score = Math.Max(pinyinScore, acronymScore);
return score;
@@ -163,8 +165,9 @@ namespace Wox.Infrastructure
{
public bool Success { get; set; }
public int Score { get; set; }
+
///
- /// hightlight string
+ /// highlight string
///
public string Value { get; set; }
}
diff --git a/Wox.Plugin/Query.cs b/Wox.Plugin/Query.cs
index 400ae741f..07b640ab8 100644
--- a/Wox.Plugin/Query.cs
+++ b/Wox.Plugin/Query.cs
@@ -6,6 +6,19 @@ namespace Wox.Plugin
{
public class Query
{
+ internal Query() { }
+
+ ///
+ /// to allow unit tests for plug ins
+ ///
+ public Query(string rawQuery, string search, string[] terms, string actionKeyword = "")
+ {
+ Search = search;
+ RawQuery = rawQuery;
+ Terms = terms;
+ ActionKeyword = actionKeyword;
+ }
+
///
/// Raw query, this includes action keyword if it has
/// We didn't recommend use this property directly. You should always use Search property.
diff --git a/Wox.Plugin/Result.cs b/Wox.Plugin/Result.cs
index 88b8679f2..2f7459170 100644
--- a/Wox.Plugin/Result.cs
+++ b/Wox.Plugin/Result.cs
@@ -110,6 +110,6 @@ namespace Wox.Plugin
///
/// Plugin ID that generate this result
///
- public string PluginID { get; set; }
+ public string PluginID { get; internal set; }
}
}
\ No newline at end of file
diff --git a/Wox.Test/FuzzyMatcherTest.cs b/Wox.Test/FuzzyMatcherTest.cs
index 9aeca0534..ce1746a3a 100644
--- a/Wox.Test/FuzzyMatcherTest.cs
+++ b/Wox.Test/FuzzyMatcherTest.cs
@@ -55,7 +55,7 @@ namespace Wox.Test
results.Add(new Result
{
Title = str,
- Score = StringMatcher.FuzzySearch("inst", str, new MatchOption()).Score
+ Score = StringMatcher.FuzzySearch("inst", str).Score
});
}
@@ -72,7 +72,7 @@ namespace Wox.Test
{
var compareString = "Can have rum only in my glass";
- var scoreResult = StringMatcher.FuzzySearch(searchString, compareString, new MatchOption()).Score;
+ var scoreResult = StringMatcher.FuzzySearch(searchString, compareString).Score;
Assert.True(scoreResult == 0);
}
@@ -92,7 +92,7 @@ namespace Wox.Test
results.Add(new Result
{
Title = str,
- Score = StringMatcher.FuzzySearch(searchTerm, str, new MatchOption()).Score
+ Score = StringMatcher.FuzzySearch(searchTerm, str).Score
});
}
@@ -135,7 +135,7 @@ namespace Wox.Test
results.Add(new Result
{
Title = str,
- Score = StringMatcher.FuzzySearch(searchTerm, str, new MatchOption()).Score
+ Score = StringMatcher.FuzzySearch(searchTerm, str).Score
});
}
@@ -173,7 +173,7 @@ namespace Wox.Test
{
var expectedPrecisionString = (StringMatcher.SearchPrecisionScore)expectedPrecisionScore;
StringMatcher.UserSettingSearchPrecision = expectedPrecisionString.ToString();
- var matchResult = StringMatcher.FuzzySearch(queryString, compareString, new MatchOption());
+ var matchResult = StringMatcher.FuzzySearch(queryString, compareString);
Debug.WriteLine("");
Debug.WriteLine("###############################################");