From 34a7a1522642f4252e6106511cb8538508bfdfa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Sun, 14 Feb 2021 13:56:27 +0800 Subject: [PATCH] Use Stream model --- Flow.Launcher.Core/Plugin/ExecutablePlugin.cs | 3 +- Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 141 ++++++++++-------- Flow.Launcher.Core/Plugin/PythonPlugin.cs | 2 +- 3 files changed, 78 insertions(+), 68 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs b/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs index d0d47aa58..13b6ac968 100644 --- a/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs +++ b/Flow.Launcher.Core/Plugin/ExecutablePlugin.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.IO; using System.Threading; using System.Threading.Tasks; using Flow.Launcher.Plugin; @@ -23,7 +24,7 @@ namespace Flow.Launcher.Core.Plugin }; } - protected override Task ExecuteQueryAsync(Query query, CancellationToken token) + protected override Task ExecuteQueryAsync(Query query, CancellationToken token) { JsonRPCServerRequestModel request = new JsonRPCServerRequestModel { diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index a37b2b68b..a5633b118 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Reflection; using System.Text.Json; using System.Threading; @@ -26,7 +27,7 @@ namespace Flow.Launcher.Core.Plugin /// public abstract string SupportedLanguage { get; set; } - protected abstract Task ExecuteQueryAsync(Query query, CancellationToken token); + protected abstract Task ExecuteQueryAsync(Query query, CancellationToken token); protected abstract string ExecuteCallback(JsonRPCRequestModel rpcRequest); protected abstract string ExecuteContextMenu(Result selectedResult); @@ -45,53 +46,66 @@ namespace Flow.Launcher.Core.Plugin } } - private List DeserializedResult(string output) + + + private List ParseResults(JsonRPCQueryResponseModel queryResponseModel) { - if (!String.IsNullOrEmpty(output)) + var results = new List(); + if (queryResponseModel.Result == null) return null; + + foreach (JsonRPCResult result in queryResponseModel.Result) { - List results = new List(); - - JsonRPCQueryResponseModel queryResponseModel = - JsonSerializer.Deserialize(output); - if (queryResponseModel.Result == null) return null; - - foreach (JsonRPCResult result in queryResponseModel.Result) + result.Action = c => { - result.Action = c => - { - if (result.JsonRPCAction == null) return false; + if (result.JsonRPCAction == null) return false; - if (!String.IsNullOrEmpty(result.JsonRPCAction.Method)) + if (!string.IsNullOrEmpty(result.JsonRPCAction.Method)) + { + if (result.JsonRPCAction.Method.StartsWith("Flow.Launcher.")) { - if (result.JsonRPCAction.Method.StartsWith("Flow.Launcher.")) + ExecuteFlowLauncherAPI(result.JsonRPCAction.Method.Substring(4), + result.JsonRPCAction.Parameters); + } + else + { + string actionReponse = ExecuteCallback(result.JsonRPCAction); + JsonRPCRequestModel jsonRpcRequestModel = + JsonSerializer.Deserialize(actionReponse); + if (jsonRpcRequestModel != null + && !string.IsNullOrEmpty(jsonRpcRequestModel.Method) + && jsonRpcRequestModel.Method.StartsWith("Flow.Launcher.")) { - ExecuteFlowLauncherAPI(result.JsonRPCAction.Method.Substring(4), - result.JsonRPCAction.Parameters); - } - else - { - string actionReponse = ExecuteCallback(result.JsonRPCAction); - JsonRPCRequestModel jsonRpcRequestModel = - JsonSerializer.Deserialize(actionReponse); - if (jsonRpcRequestModel != null - && !String.IsNullOrEmpty(jsonRpcRequestModel.Method) - && jsonRpcRequestModel.Method.StartsWith("Flow.Launcher.")) - { - ExecuteFlowLauncherAPI(jsonRpcRequestModel.Method.Substring(4), - jsonRpcRequestModel.Parameters); - } + ExecuteFlowLauncherAPI(jsonRpcRequestModel.Method.Substring(4), + jsonRpcRequestModel.Parameters); } } + } - return !result.JsonRPCAction.DontHideAfterAction; - }; - results.Add(result); - } - - return results; + return !result.JsonRPCAction.DontHideAfterAction; + }; + results.Add(result); } - return null; + return results; + } + + private async Task> DeserializedResultAsync(Stream output) + { + if (output == Stream.Null) return null; + + JsonRPCQueryResponseModel queryResponseModel = await + JsonSerializer.DeserializeAsync(output); + + return ParseResults(queryResponseModel); + } + + private List DeserializedResult(string output) + { + if (string.IsNullOrEmpty(output)) return null; + + JsonRPCQueryResponseModel queryResponseModel = + JsonSerializer.Deserialize(output); + return ParseResults(queryResponseModel); } private void ExecuteFlowLauncherAPI(string method, object[] parameters) @@ -119,15 +133,17 @@ namespace Flow.Launcher.Core.Plugin /// /// Cancellation Token /// - protected Task ExecuteAsync(string fileName, string arguments, CancellationToken token = default) + protected Task ExecuteAsync(string fileName, string arguments, CancellationToken token = default) { - ProcessStartInfo start = new ProcessStartInfo(); - start.FileName = fileName; - start.Arguments = arguments; - start.UseShellExecute = false; - start.CreateNoWindow = true; - start.RedirectStandardOutput = true; - start.RedirectStandardError = true; + ProcessStartInfo start = new ProcessStartInfo + { + FileName = fileName, + Arguments = arguments, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true + }; return ExecuteAsync(start, token); } @@ -137,7 +153,7 @@ namespace Flow.Launcher.Core.Plugin { using var process = Process.Start(startInfo); if (process == null) return string.Empty; - + using var standardOutput = process.StandardOutput; var result = standardOutput.ReadToEnd(); @@ -157,12 +173,12 @@ namespace Flow.Launcher.Core.Plugin if (result.StartsWith("DEBUG:")) { - MessageBox.Show(new Form {TopMost = true}, result.Substring(6)); + MessageBox.Show(new Form { TopMost = true }, result.Substring(6)); return string.Empty; } return result; - + } catch (Exception e) { @@ -173,7 +189,7 @@ namespace Flow.Launcher.Core.Plugin } } - protected async Task ExecuteAsync(ProcessStartInfo startInfo, CancellationToken token = default) + protected async Task ExecuteAsync(ProcessStartInfo startInfo, CancellationToken token = default) { try { @@ -181,17 +197,14 @@ namespace Flow.Launcher.Core.Plugin if (process == null) { Log.Error("|JsonRPCPlugin.ExecuteAsync|Can't start new process"); - return string.Empty; + return Stream.Null; } - using var standardOutput = process.StandardOutput; + var result = process.StandardOutput.BaseStream; token.ThrowIfCancellationRequested(); - var result = await standardOutput.ReadToEndAsync(); - token.ThrowIfCancellationRequested(); - - if (string.IsNullOrEmpty(result)) + if (!process.StandardError.EndOfStream) { using var standardError = process.StandardError; var error = await standardError.ReadToEndAsync(); @@ -200,17 +213,11 @@ namespace Flow.Launcher.Core.Plugin if (!string.IsNullOrEmpty(error)) { Log.Error($"|JsonRPCPlugin.ExecuteAsync|{error}"); - return string.Empty; + return Stream.Null; } Log.Error("|JsonRPCPlugin.ExecuteAsync|Empty standard output and standard error."); - return string.Empty; - } - - if (result.StartsWith("DEBUG:")) - { - MessageBox.Show(new Form {TopMost = true}, result.Substring(6)); - return string.Empty; + return Stream.Null; } return result; @@ -220,16 +227,18 @@ namespace Flow.Launcher.Core.Plugin Log.Exception( $"|JsonRPCPlugin.ExecuteAsync|Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>", e); - return string.Empty; + return Stream.Null; } } + + public async Task> QueryAsync(Query query, CancellationToken token) { - string output = await ExecuteQueryAsync(query, token); + var output = await ExecuteQueryAsync(query, token); try { - return DeserializedResult(output); + return await DeserializedResultAsync(output); } catch (Exception e) { diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs index 750684954..356a68a81 100644 --- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs +++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs @@ -30,7 +30,7 @@ namespace Flow.Launcher.Core.Plugin } - protected override Task ExecuteQueryAsync(Query query, CancellationToken token) + protected override Task ExecuteQueryAsync(Query query, CancellationToken token) { JsonRPCServerRequestModel request = new JsonRPCServerRequestModel {