PowerToys/Wox.Core/Plugin/JsonRPCPlugin.cs

204 lines
7.4 KiB
C#
Raw Normal View History

2016-01-07 05:34:42 +08:00
using System;
using System.Collections.Generic;
2014-07-06 22:57:11 +08:00
using System.Diagnostics;
using System.IO;
2014-07-10 23:57:08 +08:00
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
2014-12-26 22:51:04 +08:00
using System.Windows.Forms;
2014-07-06 22:57:11 +08:00
using Newtonsoft.Json;
2015-11-09 09:32:33 +08:00
using Wox.Infrastructure.Exception;
2014-09-19 16:57:48 +08:00
using Wox.Infrastructure.Logger;
2014-07-06 22:57:11 +08:00
using Wox.Plugin;
2014-12-26 19:36:43 +08:00
namespace Wox.Core.Plugin
2014-07-06 22:57:11 +08:00
{
2014-12-26 19:36:43 +08:00
/// <summary>
/// Represent the plugin that using JsonPRC
/// every JsonRPC plugin should has its own plugin instance
2014-12-26 19:36:43 +08:00
/// </summary>
2017-04-11 21:34:04 +08:00
internal abstract class JsonRPCPlugin : IPlugin, IContextMenu
2014-07-06 22:57:11 +08:00
{
protected PluginInitContext context;
public const string JsonRPC = "JsonRPC";
2014-07-06 22:57:11 +08:00
2014-12-26 19:36:43 +08:00
/// <summary>
/// The language this JsonRPCPlugin support
/// </summary>
public abstract string SupportedLanguage { get; set; }
2014-07-06 22:57:11 +08:00
2014-07-07 23:05:06 +08:00
protected abstract string ExecuteQuery(Query query);
2014-12-26 19:36:43 +08:00
protected abstract string ExecuteCallback(JsonRPCRequestModel rpcRequest);
2017-04-11 21:34:04 +08:00
protected abstract string ExecuteContextMenu(Result selectedResult);
2014-07-06 22:57:11 +08:00
public List<Result> Query(Query query)
{
2014-07-07 23:05:06 +08:00
string output = ExecuteQuery(query);
try
{
return DeserializedResult(output);
}
catch (Exception e)
{
Log.Exception($"|JsonRPCPlugin.Query|Exception when query <{query}>", e);
return null;
}
}
2017-04-11 21:34:04 +08:00
public List<Result> LoadContextMenus(Result selectedResult)
{
string output = ExecuteContextMenu(selectedResult);
try
{
return DeserializedResult(output);
}
catch (Exception e)
{
Log.Exception($"|JsonRPCPlugin.LoadContextMenus|Exception on result <{selectedResult}>", e);
return null;
}
}
private List<Result> DeserializedResult(string output)
{
if (!String.IsNullOrEmpty(output))
2014-07-06 22:57:11 +08:00
{
2017-04-11 21:32:51 +08:00
List<Result> results = new List<Result>();
2014-07-07 23:05:06 +08:00
2017-04-11 21:32:51 +08:00
JsonRPCQueryResponseModel queryResponseModel = JsonConvert.DeserializeObject<JsonRPCQueryResponseModel>(output);
if (queryResponseModel.Result == null) return null;
2014-07-18 23:12:50 +08:00
2017-04-11 21:32:51 +08:00
foreach (JsonRPCResult result in queryResponseModel.Result)
{
JsonRPCResult result1 = result;
result.Action = c =>
2014-07-06 22:57:11 +08:00
{
2017-04-11 21:32:51 +08:00
if (result1.JsonRPCAction == null) return false;
2017-04-11 21:32:51 +08:00
if (!String.IsNullOrEmpty(result1.JsonRPCAction.Method))
{
if (result1.JsonRPCAction.Method.StartsWith("Wox."))
2014-07-06 22:57:11 +08:00
{
2017-04-11 21:32:51 +08:00
ExecuteWoxAPI(result1.JsonRPCAction.Method.Substring(4), result1.JsonRPCAction.Parameters);
}
else
{
string actionReponse = ExecuteCallback(result1.JsonRPCAction);
JsonRPCRequestModel jsonRpcRequestModel = JsonConvert.DeserializeObject<JsonRPCRequestModel>(actionReponse);
if (jsonRpcRequestModel != null
&& !String.IsNullOrEmpty(jsonRpcRequestModel.Method)
&& jsonRpcRequestModel.Method.StartsWith("Wox."))
2014-07-10 23:57:08 +08:00
{
2017-04-11 21:32:51 +08:00
ExecuteWoxAPI(jsonRpcRequestModel.Method.Substring(4), jsonRpcRequestModel.Parameters);
2014-07-10 23:57:08 +08:00
}
}
2017-04-11 21:32:51 +08:00
}
return !result1.JsonRPCAction.DontHideAfterAction;
};
results.Add(result);
}
return results;
2014-07-06 22:57:11 +08:00
}
2017-04-11 21:34:04 +08:00
else
{
return null;
}
2014-07-06 22:57:11 +08:00
}
2014-07-10 23:57:08 +08:00
private void ExecuteWoxAPI(string method, object[] parameters)
{
2014-12-26 22:51:04 +08:00
MethodInfo methodInfo = PluginManager.API.GetType().GetMethod(method);
2015-02-03 18:32:16 +08:00
if (methodInfo != null)
2014-07-10 23:57:08 +08:00
{
try
{
2014-12-26 22:51:04 +08:00
methodInfo.Invoke(PluginManager.API, parameters);
2014-07-10 23:57:08 +08:00
}
2016-01-07 05:34:42 +08:00
catch (Exception)
2014-07-10 23:57:08 +08:00
{
#if (DEBUG)
{
throw;
}
#endif
}
}
}
2014-07-07 23:05:06 +08:00
/// <summary>
/// Execute external program and return the output
/// </summary>
/// <param name="fileName"></param>
/// <param name="arguments"></param>
/// <returns></returns>
protected string Execute(string fileName, string arguments)
2014-07-18 20:00:55 +08:00
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = fileName;
start.Arguments = arguments;
start.UseShellExecute = false;
start.CreateNoWindow = true;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
return Execute(start);
}
protected string Execute(ProcessStartInfo startInfo)
2014-07-06 22:57:11 +08:00
{
try
{
2017-01-30 08:26:11 +08:00
using (var process = Process.Start(startInfo))
2014-07-06 22:57:11 +08:00
{
if (process != null)
2014-07-06 22:57:11 +08:00
{
2017-01-30 08:26:11 +08:00
using (var standardOutput = process.StandardOutput)
2014-07-06 22:57:11 +08:00
{
2017-01-30 08:26:11 +08:00
var result = standardOutput.ReadToEnd();
if (string.IsNullOrEmpty(result))
2014-07-18 20:00:55 +08:00
{
2017-01-30 08:26:11 +08:00
using (var standardError = process.StandardError)
2014-07-18 20:00:55 +08:00
{
2017-01-30 08:26:11 +08:00
var error = standardError.ReadToEnd();
if (!string.IsNullOrEmpty(error))
{
Log.Error($"|JsonRPCPlugin.Execute|{error}");
return string.Empty;
}
else
2014-07-18 20:00:55 +08:00
{
2017-01-30 08:26:11 +08:00
Log.Error("|JsonRPCPlugin.Execute|Empty standard output and standard error.");
return string.Empty;
2014-07-18 20:00:55 +08:00
}
}
}
2017-01-30 08:26:11 +08:00
else if (result.StartsWith("DEBUG:"))
{
2017-04-11 21:32:51 +08:00
MessageBox.Show(new Form { TopMost = true }, result.Substring(6));
2017-01-30 08:26:11 +08:00
return string.Empty;
}
else
{
return result;
}
2014-07-06 22:57:11 +08:00
}
}
2017-01-30 08:26:11 +08:00
else
{
Log.Error("|JsonRPCPlugin.Execute|Can't start new process");
return string.Empty;
}
2014-07-06 22:57:11 +08:00
}
}
catch (Exception e)
2014-07-06 22:57:11 +08:00
{
2017-01-30 08:26:11 +08:00
Log.Exception($"|JsonRPCPlugin.Execute|Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>", e);
return string.Empty;
2014-07-06 22:57:11 +08:00
}
}
public void Init(PluginInitContext ctx)
{
2014-12-26 19:36:43 +08:00
context = ctx;
2014-07-06 22:57:11 +08:00
}
}
2017-04-11 21:34:04 +08:00
}