diff --git a/Deploy/Cleanup.bat b/Deploy/Cleanup.bat deleted file mode 100644 index 5c5a581362..0000000000 --- a/Deploy/Cleanup.bat +++ /dev/null @@ -1,23 +0,0 @@ -echo "start clean" -cd /d %~dp0 - -REM Clean Plugins -echo "clean plugins" -cd ..\Output\Release\Plugins -del NLog.dll /s -del NLog.config /s -del Wox.Plugin.pdb /s -del Wox.Plugin.dll /s -del Wox.Core.dll /s -del Wox.Core.pdb /s -del ICSharpCode.SharpZipLib.dll /s -del NAppUpdate.Framework.dll /s -del Wox.Infrastructure.dll /s -del Wox.Infrastructure.pdb /s -del Newtonsoft.Json.dll /s -del WindowsInput.dll /s - -REM Clean Wox -echo "wox" -cd .. -del *.xml diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index 557729f95f..bb0a212726 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -6,12 +6,13 @@ using System.Reflection; using System.Windows.Forms; using WindowsInput; using WindowsInput.Native; +using Wox.Infrastructure; using Wox.Infrastructure.Hotkey; using Control = System.Windows.Controls.Control; namespace Wox.Plugin.CMD { - public class CMD : IPlugin, ISettingProvider, IPluginI18n + public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantSearch { private PluginInitContext context; private bool WinRStroked; @@ -37,6 +38,7 @@ namespace Wox.Plugin.CMD context.API.PushResults(query, context.CurrentPluginMetadata, history); pushedResults.AddRange(history); + try { string basedir = null; @@ -72,6 +74,7 @@ namespace Wox.Plugin.CMD } } catch (Exception) { } + } return results; } @@ -207,5 +210,11 @@ namespace Wox.Plugin.CMD { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + + public bool IsInstantSearch(string query) + { + if (query.StartsWith(">")) return true; + return false; + } } -} +} \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj index 78a2469ebb..e25b8e2256 100644 --- a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj +++ b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj @@ -36,9 +36,9 @@ - - packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - True + + False + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll @@ -82,6 +82,7 @@ PreserveNewest + PreserveNewest @@ -93,7 +94,6 @@ - PreserveNewest diff --git a/Plugins/Wox.Plugin.Everything/x64/Everything.dll b/Plugins/Wox.Plugin.Everything/x64/Everything.dll new file mode 100644 index 0000000000..2b7abd03cb Binary files /dev/null and b/Plugins/Wox.Plugin.Everything/x64/Everything.dll differ diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs b/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs index d771bc3b90..8a2a43011d 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs @@ -9,7 +9,7 @@ using Wox.Plugin.WebSearch.SuggestionSources; namespace Wox.Plugin.WebSearch { - public class WebSearchPlugin : IPlugin, ISettingProvider,IPluginI18n + public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantSearch { private PluginInitContext context; @@ -97,5 +97,16 @@ namespace Wox.Plugin.WebSearch { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + + public bool IsInstantSearch(string query) + { + var strings = query.Split(' '); + if (strings.Length > 1) + { + return WebSearchStorage.Instance.EnableWebSearchSuggestion && + WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == strings[0] && o.Enabled); + } + return false; + } } } diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 399992fa6f..c9d15ec0b9 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -20,6 +20,9 @@ namespace Wox.Core.Plugin public static class PluginManager { public const string ActionKeywordWildcardSign = "*"; + private static List pluginMetadatas; + private static List instantSearches = new List(); + public static String DebuggerMode { get; private set; } public static IPublicAPI API { get; private set; } @@ -31,7 +34,6 @@ namespace Wox.Core.Plugin /// private static List pluginDirectories = new List(); - private static void SetupPluginDirectories() { pluginDirectories.Add(PluginDirectory); @@ -72,7 +74,7 @@ namespace Wox.Core.Plugin API = api; plugins.Clear(); - List pluginMetadatas = PluginConfig.Parse(pluginDirectories); + pluginMetadatas = PluginConfig.Parse(pluginDirectories); plugins.AddRange(new CSharpPluginLoader().LoadPlugin(pluginMetadatas)); plugins.AddRange(new JsonRPCPluginLoader().LoadPlugin(pluginMetadatas)); @@ -95,6 +97,8 @@ namespace Wox.Core.Plugin } }); } + + LoadInstantSearches(); } public static void InstallPlugin(string path) @@ -140,6 +144,46 @@ namespace Wox.Core.Plugin DebuggerMode = path; } + public static bool IsInstantSearch(string query) + { + return LoadInstantSearches().Any(o => o.IsInstantSearch(query)); + } + + private static List LoadInstantSearches() + { + if (instantSearches.Count > 0) return instantSearches; + List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); + + foreach (PluginMetadata metadata in CSharpPluginMetadatas) + { + try + { + Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); + List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IInstantSearch))).ToList(); + if (types.Count == 0) + { + continue; + } + + foreach (Type type in types) + { + instantSearches.Add(Activator.CreateInstance(type) as IInstantSearch); + } + } + catch (System.Exception e) + { + Log.Error(string.Format("Couldn't load plugin {0}: {1}", metadata.Name, e.Message)); +#if (DEBUG) + { + throw; + } +#endif + } + } + + return instantSearches; + } + /// /// get specified plugin, return null if not found /// diff --git a/Wox.Core/Updater/Release.cs b/Wox.Core/Updater/Release.cs new file mode 100644 index 0000000000..e2e157a943 --- /dev/null +++ b/Wox.Core/Updater/Release.cs @@ -0,0 +1,11 @@ +namespace Wox.Core.Updater +{ + public class Release + { + public string version { get; set; } + public string download_link { get; set; } + public string download_link1 { get; set; } + public string download_link2 { get; set; } + public string description { get; set; } + } +} \ No newline at end of file diff --git a/Wox.Core/Version/SemanticVersion.cs b/Wox.Core/Updater/SemanticVersion.cs similarity index 95% rename from Wox.Core/Version/SemanticVersion.cs rename to Wox.Core/Updater/SemanticVersion.cs index 9ba46238c0..693ce73eef 100644 --- a/Wox.Core/Version/SemanticVersion.cs +++ b/Wox.Core/Updater/SemanticVersion.cs @@ -1,11 +1,7 @@ using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Wox.Core.Exception; -namespace Wox.Core.Version +namespace Wox.Core.Updater { public class SemanticVersion : IComparable { diff --git a/Wox.Core/Updater/UpdaterManager.cs b/Wox.Core/Updater/UpdaterManager.cs index c89d651db5..6d8b9705ff 100644 --- a/Wox.Core/Updater/UpdaterManager.cs +++ b/Wox.Core/Updater/UpdaterManager.cs @@ -1,13 +1,15 @@ - -using System; +using System; using System.IO; +using System.Reflection; using System.Windows.Forms; using System.Windows.Threading; using NAppUpdate.Framework; using NAppUpdate.Framework.Common; using NAppUpdate.Framework.Sources; +using Newtonsoft.Json; using Wox.Core.i18n; using Wox.Core.UserSettings; +using Wox.Infrastructure.Http; using Wox.Infrastructure.Logger; namespace Wox.Core.Updater @@ -15,6 +17,9 @@ namespace Wox.Core.Updater public class UpdaterManager { private static UpdaterManager instance; + private const string VersionCheckURL = "https://api.getwox.com/release/latest/"; + private const string UpdateFeedURL = "http://127.0.0.1:8888/Update.xml"; + private static SemanticVersion currentVersion; public static UpdaterManager Instance { @@ -33,12 +38,45 @@ namespace Wox.Core.Updater UpdateManager.Instance.UpdateSource = GetUpdateSource(); } - public bool IsUpdateAvailable() + public SemanticVersion CurrentVersion { - return UpdateManager.Instance.UpdatesAvailable > 0; + get + { + if (currentVersion == null) + { + currentVersion = new SemanticVersion(Assembly.GetExecutingAssembly().GetName().Version); + } + return currentVersion; + } + } + + private bool IsNewerThanCurrent(Release release) + { + if (release == null) return false; + + return new SemanticVersion(release.version) > CurrentVersion; } public void CheckUpdate() + { + string json = HttpRequest.Get(VersionCheckURL, HttpProxy.Instance); + if (!string.IsNullOrEmpty(json)) + { + try + { + Release newRelease = JsonConvert.DeserializeObject(json); + if (IsNewerThanCurrent(newRelease)) + { + StartUpdate(); + } + } + catch + { + } + } + } + + private void StartUpdate() { UpdateManager updManager = UpdateManager.Instance; updManager.BeginCheckForUpdates(asyncResult => @@ -104,7 +142,7 @@ namespace Wox.Core.Updater { // Normally this would be a web based source. // But for the demo app, we prepare an in-memory source. - var source = new SimpleWebSource("http://127.0.0.1:8888/Update.xml"); + var source = new SimpleWebSource(UpdateFeedURL); return source; } } diff --git a/Wox.Core/Version/VersionManager.cs b/Wox.Core/Version/VersionManager.cs deleted file mode 100644 index 994e46e164..0000000000 --- a/Wox.Core/Version/VersionManager.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; - -namespace Wox.Core.Version -{ - public class VersionManager - { - private static VersionManager versionManager; - private static SemanticVersion currentVersion; - - public static VersionManager Instance - { - get - { - if (versionManager == null) - { - versionManager = new VersionManager(); - } - return versionManager; - } - } - - private VersionManager() { } - - public SemanticVersion CurrentVersion - { - get - { - if (currentVersion == null) - { - currentVersion = new SemanticVersion(Assembly.GetExecutingAssembly().GetName().Version); - } - return currentVersion; - } - } - } -} diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index e4d2764109..032f760103 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -69,6 +69,7 @@ + @@ -99,8 +100,7 @@ - - + diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index ec041fb7cd..7a6ec983c5 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -16,8 +16,8 @@ using Wox.Core; using Wox.Core.Exception; using Wox.Core.i18n; using Wox.Core.UI; +using Wox.Core.Updater; using Wox.Core.UserSettings; -using Wox.Core.Version; using Wox.Infrastructure.Http; namespace Wox.CrashReporter @@ -36,7 +36,7 @@ namespace Wox.CrashReporter private void SetException(Exception exception) { tbSummary.AppendText(exception.Message); - tbVersion.Text = VersionManager.Instance.CurrentVersion.ToString(); + tbVersion.Text = UpdaterManager.Instance.CurrentVersion.ToString(); tbDatetime.Text = DateTime.Now.ToString(); tbStackTrace.AppendText(exception.StackTrace); tbSource.Text = exception.Source; diff --git a/Wox.Infrastructure/NLog.config b/Wox.Infrastructure/NLog.config index ec19a82787..9dcf31def0 100644 --- a/Wox.Infrastructure/NLog.config +++ b/Wox.Infrastructure/NLog.config @@ -15,11 +15,9 @@ Error - error messages Fatal - very serious errors--> - - + - \ No newline at end of file diff --git a/Wox.Plugin/IInstantSearch.cs b/Wox.Plugin/IInstantSearch.cs new file mode 100644 index 0000000000..0799f45f4b --- /dev/null +++ b/Wox.Plugin/IInstantSearch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Wox.Plugin +{ + public interface IInstantSearch + { + bool IsInstantSearch(string query); + } +} diff --git a/Wox.Plugin/Properties/AssemblyInfo.cs b/Wox.Plugin/Properties/AssemblyInfo.cs index a0913e1a59..a7fb46756c 100644 --- a/Wox.Plugin/Properties/AssemblyInfo.cs +++ b/Wox.Plugin/Properties/AssemblyInfo.cs @@ -17,4 +17,4 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("Wox")] [assembly: InternalsVisibleTo("Wox.Core")] -[assembly: InternalsVisibleTo("Wox.Test")] \ No newline at end of file +[assembly: InternalsVisibleTo("Wox.Test")] diff --git a/Wox.Plugin/Wox.Plugin.csproj b/Wox.Plugin/Wox.Plugin.csproj index 8f7aa59418..424272a200 100644 --- a/Wox.Plugin/Wox.Plugin.csproj +++ b/Wox.Plugin/Wox.Plugin.csproj @@ -46,6 +46,7 @@ + diff --git a/Wox.Test/SemanticVersionTest.cs b/Wox.Test/SemanticVersionTest.cs index c4abdcbbde..81e6e5ddac 100644 --- a/Wox.Test/SemanticVersionTest.cs +++ b/Wox.Test/SemanticVersionTest.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; -using Wox.Core.Version; +using Wox.Core.Updater; namespace Wox.Test { diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index dbb12dca6c..e551a50dd1 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -337,18 +337,27 @@ namespace Wox if (pnlResult.Dirty) pnlResult.Clear(); }, TimeSpan.FromMilliseconds(100), null); queryHasReturn = false; - var q = new Query(lastQuery); - FireBeforeWoxQueryEvent(q); - Query(q); + Query query = new Query(lastQuery); + FireBeforeWoxQueryEvent(query); + Query(query); Dispatcher.DelayInvoke("ShowProgressbar", originQuery => { - if (!queryHasReturn && originQuery == lastQuery && !string.IsNullOrEmpty(lastQuery)) + if (!queryHasReturn && originQuery == tbQuery.Text && !string.IsNullOrEmpty(lastQuery)) { StartProgress(); } - }, TimeSpan.FromMilliseconds(150), lastQuery); - FireAfterWoxQueryEvent(q); - }, TimeSpan.FromMilliseconds(200)); + }, TimeSpan.FromMilliseconds(150), tbQuery.Text); + FireAfterWoxQueryEvent(query); + }, TimeSpan.FromMilliseconds(GetSearchDelay(lastQuery))); + } + + private int GetSearchDelay(string query) + { + if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantSearch(query)) + { + return 0; + } + return 200; } private void FireAfterWoxQueryEvent(Query q) diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 9b8b5f78be..b607281b01 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -20,8 +20,8 @@ using System.Windows.Data; using Microsoft.Win32; using Wox.Core.i18n; using Wox.Core.Theme; +using Wox.Core.Updater; using Wox.Core.UserSettings; -using Wox.Core.Version; namespace Wox { @@ -217,7 +217,7 @@ namespace Wox #region About - tbVersion.Text = VersionManager.Instance.CurrentVersion.ToString(); + tbVersion.Text = UpdaterManager.Instance.CurrentVersion.ToString(); string activateTimes = string.Format(InternationalizationManager.Instance.GetTranslation("about_activate_times"), UserSettingStorage.Instance.ActivateTimes); tbActivatedTimes.Text = activateTimes; diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 5bfe619990..586ba46bfe 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -313,10 +313,24 @@ - xcopy /Y $(ProjectDir)Themes\* $(TargetDir)Themes\ -xcopy /Y /E $(ProjectDir)Images\* $(TargetDir)Images\ -del /s /q "$(TargetDir)*.xml" -xcopy /Y /D /E $(SolutionDir)PythonHome\* $(TargetDir)PythonHome\ + xcopy /Y $(ProjectDir)Themes\* $(TargetDir)Themes\ +xcopy /Y /E $(ProjectDir)Images\* $(TargetDir)Images\ +xcopy /Y /D /E $(SolutionDir)PythonHome\* $(TargetDir)PythonHome\ + +cd "$(TargetDir)" & del /s /q *.xml + +cd "$(TargetDir)Plugins" & del /s /q NLog.dll +cd "$(TargetDir)Plugins" & del /s /q NLog.config +cd "$(TargetDir)Plugins" & del /s /q Wox.Plugin.pdb +cd "$(TargetDir)Plugins" & del /s /q Wox.Plugin.dll +cd "$(TargetDir)Plugins" & del /s /q Wox.Core.dll +cd "$(TargetDir)Plugins" & del /s /q Wox.Core.pdb +cd "$(TargetDir)Plugins" & del /s /q ICSharpCode.SharpZipLib.dll +cd "$(TargetDir)Plugins" & del /s /q NAppUpdate.Framework.dll +cd "$(TargetDir)Plugins" & del /s /q Wox.Infrastructure.dll +cd "$(TargetDir)Plugins" & del /s /q Wox.Infrastructure.pdb +cd "$(TargetDir)Plugins" & del /s /q Newtonsoft.Json.dll +cd "$(TargetDir)Plugins" & del /s /q WindowsInput.dll