diff --git a/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs b/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs index 36defbe9af..91b24ad1ae 100644 --- a/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs +++ b/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs @@ -10,6 +10,7 @@ namespace Wox.Core.Plugin internal class ExecutablePlugin : JsonRPCPlugin { private readonly ProcessStartInfo _startInfo; + public override string SupportedLanguage { get; set; } = AllowedLanguage.Executable; public ExecutablePlugin(string filename) diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonPRCModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonPRCModel.cs index 23c3dbd8fc..5c75e11418 100644 --- a/src/modules/launcher/Wox.Core/Plugin/JsonPRCModel.cs +++ b/src/modules/launcher/Wox.Core/Plugin/JsonPRCModel.cs @@ -1,16 +1,19 @@ - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * + * * When execute a query: * Wox -------JsonRPCServerRequestModel--------> client * Wox <------JsonRPCQueryResponseModel--------- client - * + * * When execute a action (which mean user select an item in reulst item): * Wox -------JsonRPCServerRequestModel--------> client * Wox <------JsonRPCResponseModel-------------- client - * + * */ using System.Collections.Generic; @@ -74,25 +77,29 @@ namespace Wox.Core.Plugin { return "null"; } + if (parameter is string) { return string.Format(@"\""{0}\""", ReplaceEscapes(parameter.ToString())); } + if (parameter is int || parameter is float || parameter is double) { return string.Format(@"{0}", parameter); } + if (parameter is bool) { return string.Format(@"{0}", parameter.ToString().ToLower()); } + return parameter.ToString(); } private string ReplaceEscapes(string str) { - return str.Replace(@"\", @"\\") //Escapes in ProcessStartInfo - .Replace(@"\", @"\\") //Escapes itself when passed to client + return str.Replace(@"\", @"\\") // Escapes in ProcessStartInfo + .Replace(@"\", @"\\") // Escapes itself when passed to client .Replace(@"""", @"\\"""""); } } diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs index d536cd0a3d..0e825f3279 100644 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs +++ b/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs @@ -28,7 +28,9 @@ namespace Wox.Core.Plugin public abstract string SupportedLanguage { get; set; } protected abstract string ExecuteQuery(Query query); + protected abstract string ExecuteCallback(JsonRPCRequestModel rpcRequest); + protected abstract string ExecuteContextMenu(Result selectedResult); public List Query(Query query) @@ -50,10 +52,10 @@ namespace Wox.Core.Plugin string output = ExecuteContextMenu(selectedResult); try { - //This should not hit. If it does it's because Wox shares the same interface for querying context menu items as well as search results. In this case please file a bug. - //To my knowledge we aren't supporting this JSonRPC commands in Launcher, and am not able to repro this, but I will leave this here for the time being in case I'm proven wrong. - //We should remove this, or identify and test officially supported use cases and Deserialize this properly. - //return DeserializedResult(output); + // This should not hit. If it does it's because Wox shares the same interface for querying context menu items as well as search results. In this case please file a bug. + // To my knowledge we aren't supporting this JSonRPC commands in Launcher, and am not able to repro this, but I will leave this here for the time being in case I'm proven wrong. + // We should remove this, or identify and test officially supported use cases and Deserialize this properly. + // return DeserializedResult(output); throw new NotImplementedException(); } catch (Exception e) @@ -97,10 +99,12 @@ namespace Wox.Core.Plugin } } } + return !result1.JsonRPCAction.DontHideAfterAction; }; results.Add(result); } + return results; } else @@ -120,7 +124,7 @@ namespace Wox.Core.Plugin } catch (Exception) { -#if (DEBUG) +#if DEBUG { throw; } diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs b/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs index 747407d109..f0a3a13e75 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs @@ -12,7 +12,6 @@ using Wox.Plugin; namespace Wox.Core.Plugin { - internal abstract class PluginConfig { private const string PluginConfigName = "plugin.json"; @@ -72,8 +71,10 @@ namespace Wox.Core.Plugin { metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; + // for plugins which doesn't has ActionKeywords key metadata.ActionKeywords = metadata.ActionKeywords ?? new List { metadata.ActionKeyword }; + // for plugin still use old ActionKeyword metadata.ActionKeyword = metadata.ActionKeywords?[0]; } diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs b/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs index 701cfd14db..d19fb540ea 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs @@ -22,6 +22,7 @@ namespace Wox.Core.Plugin { Directory.Delete(tempFolder, true); } + UnZip(path, tempFolder, true); string iniPath = Path.Combine(tempFolder, "plugin.json"); @@ -71,21 +72,21 @@ namespace Wox.Core.Plugin { if (existingPlugin != null && Directory.Exists(existingPlugin.Metadata.PluginDirectory)) { - //when plugin is in use, we can't delete them. That's why we need to make plugin folder a random name + // when plugin is in use, we can't delete them. That's why we need to make plugin folder a random name File.Create(Path.Combine(existingPlugin.Metadata.PluginDirectory, "NeedDelete.txt")).Close(); } UnZip(path, newPluginPath, true); Directory.Delete(tempFolder, true); - //existing plugins could be loaded by the application, - //if we try to delete those kind of plugins, we will get a error that indicate the - //file is been used now. - //current solution is to restart wox. Ugly. - //if (MainWindow.Initialized) - //{ + // existing plugins could be loaded by the application, + // if we try to delete those kind of plugins, we will get a error that indicate the + // file is been used now. + // current solution is to restart wox. Ugly. + // if (MainWindow.Initialized) + // { // Plugins.Initialize(); - //} + // } if (MessageBox.Show($"You have installed plugin {plugin.Name} successfully.{Environment.NewLine}" + "Restart Wox to take effect?", "Install plugin", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) @@ -114,7 +115,7 @@ namespace Wox.Core.Plugin catch (Exception) { string error = $"Parse plugin config {configPath} failed: json format is not valid"; -#if (DEBUG) +#if DEBUG { throw new Exception(error); } @@ -125,17 +126,18 @@ namespace Wox.Core.Plugin if (!AllowedLanguage.IsAllowed(metadata.Language)) { string error = $"Parse plugin config {configPath} failed: invalid language {metadata.Language}"; -#if (DEBUG) +#if DEBUG { throw new Exception(error); } #endif return null; } + if (!File.Exists(metadata.ExecuteFilePath)) { string error = $"Parse plugin config {configPath} failed: ExecuteFile {metadata.ExecuteFilePath} didn't exist"; -#if (DEBUG) +#if DEBUG { throw new Exception(error); } @@ -147,7 +149,7 @@ namespace Wox.Core.Plugin } /// - /// unzip + /// unzip /// /// The zipped file. /// The STR directory. @@ -192,6 +194,7 @@ namespace Wox.Core.Plugin else break; } + streamWriter.Close(); } } diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs b/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs index 6d8c695615..269a8239b7 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs @@ -26,14 +26,14 @@ namespace Wox.Core.Plugin /// /// Directories that will hold Wox plugin directory /// - public static List AllPlugins { get; private set; } + public static readonly List GlobalPlugins = new List(); public static readonly Dictionary NonGlobalPlugins = new Dictionary(); public static IPublicAPI API { private set; get; } - // todo happlebao, this should not be public, the indicator function should be embedded + // todo happlebao, this should not be public, the indicator function should be embedded public static PluginsSettings Settings; private static List _metadatas; private static readonly string[] Directories = { Constant.PreinstalledDirectory, Constant.PluginsDirectory }; @@ -255,6 +255,7 @@ namespace Wox.Core.Plugin { NonGlobalPlugins[newActionKeyword] = plugin; } + plugin.Metadata.ActionKeywords.Add(newActionKeyword); } diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs b/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs index 8616d881ef..faf935c6d5 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs @@ -35,7 +35,6 @@ namespace Wox.Core.Plugin { var milliseconds = Stopwatch.Debug($"|PluginsLoader.CSharpPlugins|Constructor init cost for {metadata.Name}", () => { - #if DEBUG var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath); var types = assembly.GetTypes(); @@ -83,6 +82,7 @@ namespace Wox.Core.Plugin }); metadata.InitTime += milliseconds; } + return plugins; } diff --git a/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs b/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs index 8e2e4ac726..b88aed8f7c 100644 --- a/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs +++ b/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs @@ -43,6 +43,7 @@ namespace Wox.Core.Plugin RawQuery = rawQuery, ActionKeyword = actionKeyword, Search = search, + // Obsolete value initialisation ActionName = actionKeyword, ActionParameters = actionParameters diff --git a/src/modules/launcher/Wox.Core/Resource/FontHelper.cs b/src/modules/launcher/Wox.Core/Resource/FontHelper.cs index 7680bacd39..dc64e24ce0 100644 --- a/src/modules/launcher/Wox.Core/Resource/FontHelper.cs +++ b/src/modules/launcher/Wox.Core/Resource/FontHelper.cs @@ -12,6 +12,7 @@ namespace Wox.Core.Resource public static class FontHelper { static FontWeightConverter fontWeightConverter = new FontWeightConverter(); + public static FontWeight GetFontWeightFromInvariantStringOrNormal(string value) { if (value == null) return FontWeights.Normal; @@ -27,6 +28,7 @@ namespace Wox.Core.Resource } static FontStyleConverter fontStyleConverter = new FontStyleConverter(); + public static FontStyle GetFontStyleFromInvariantStringOrNormal(string value) { if (value == null) return FontStyles.Normal; @@ -42,6 +44,7 @@ namespace Wox.Core.Resource } static FontStretchConverter fontStretchConverter = new FontStretchConverter(); + public static FontStretch GetFontStretchFromInvariantStringOrNormal(string value) { if (value == null) return FontStretches.Normal; diff --git a/src/modules/launcher/Wox.Core/Resource/Internationalization.cs b/src/modules/launcher/Wox.Core/Resource/Internationalization.cs index 7fb3fdbf8d..a8a0aded21 100644 --- a/src/modules/launcher/Wox.Core/Resource/Internationalization.cs +++ b/src/modules/launcher/Wox.Core/Resource/Internationalization.cs @@ -19,6 +19,7 @@ namespace Wox.Core.Resource public class Internationalization { public Settings Settings { get; set; } + private const string Folder = "Languages"; private const string DefaultFile = "en.xaml"; private const string Extension = ".xaml"; @@ -29,6 +30,7 @@ namespace Wox.Core.Resource { AddPluginLanguageDirectories(); LoadDefaultLanguage(); + // we don't want to load /Languages/en.xaml twice // so add wox language directory after load plugin language files AddWoxLanguageDirectory(); @@ -97,6 +99,7 @@ namespace Wox.Core.Resource { LoadLanguage(language); } + UpdatePluginMetadataTranslations(); } diff --git a/src/modules/launcher/Wox.Core/Resource/InternationalizationManager.cs b/src/modules/launcher/Wox.Core/Resource/InternationalizationManager.cs index 474a85a29d..eaaa1723e7 100644 --- a/src/modules/launcher/Wox.Core/Resource/InternationalizationManager.cs +++ b/src/modules/launcher/Wox.Core/Resource/InternationalizationManager.cs @@ -23,6 +23,7 @@ namespace Wox.Core.Resource } } } + return instance; } } diff --git a/src/modules/launcher/Wox.Core/Wox.Core.csproj b/src/modules/launcher/Wox.Core/Wox.Core.csproj index 25a66d3e42..17cf407ad4 100644 --- a/src/modules/launcher/Wox.Core/Wox.Core.csproj +++ b/src/modules/launcher/Wox.Core/Wox.Core.csproj @@ -67,7 +67,7 @@ -