diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index d7df11f83..9e932a508 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -55,6 +55,7 @@ + diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index 431458881..5e44bef86 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -12,6 +12,7 @@ using System.Windows.Forms; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Plugin; using JetBrains.Annotations; +using Microsoft.IO; namespace Flow.Launcher.Core.Plugin { @@ -33,9 +34,11 @@ namespace Flow.Launcher.Core.Plugin protected abstract string ExecuteCallback(JsonRPCRequestModel rpcRequest); protected abstract string ExecuteContextMenu(Result selectedResult); + private static readonly RecyclableMemoryStreamManager BufferManager = new(); + public List LoadContextMenus(Result selectedResult) { - string output = ExecuteContextMenu(selectedResult); + var output = ExecuteContextMenu(selectedResult); try { return DeserializedResult(output); @@ -61,12 +64,23 @@ namespace Flow.Launcher.Core.Plugin { if (output == Stream.Null) return null; - var queryResponseModel = await - JsonSerializer.DeserializeAsync(output, options); + try + { + var queryResponseModel = + await JsonSerializer.DeserializeAsync(output, options); - await output.DisposeAsync(); - - return ParseResults(queryResponseModel); + return ParseResults(queryResponseModel); + } + catch (JsonException e) + { + Log.Exception(GetType().FullName, "Unexpected Json Input", e); + } + finally + { + await output.DisposeAsync(); + } + + return null; } private List DeserializedResult(string output) @@ -81,7 +95,6 @@ namespace Flow.Launcher.Core.Plugin private List ParseResults(JsonRPCQueryResponseModel queryResponseModel) { - var results = new List(); if (queryResponseModel.Result == null) return null; if (!string.IsNullOrEmpty(queryResponseModel.DebugMessage)) @@ -89,7 +102,7 @@ namespace Flow.Launcher.Core.Plugin context.API.ShowMsg(queryResponseModel.DebugMessage); } - foreach (JsonRPCResult result in queryResponseModel.Result) + foreach (var result in queryResponseModel.Result) { result.Action = c => { @@ -114,7 +127,8 @@ namespace Flow.Launcher.Core.Plugin return !result.JsonRPCAction.DontHideAfterAction; } - var jsonRpcRequestModel = JsonSerializer.Deserialize(actionResponse, options); + var jsonRpcRequestModel = + JsonSerializer.Deserialize(actionResponse, options); if (jsonRpcRequestModel?.Method?.StartsWith("Flow.Launcher.") ?? false) { @@ -125,9 +139,12 @@ namespace Flow.Launcher.Core.Plugin return !result.JsonRPCAction.DontHideAfterAction; }; - results.Add(result); } + var results = new List(); + + results.AddRange(queryResponseModel.Result); + return results; } @@ -226,7 +243,21 @@ namespace Flow.Launcher.Core.Plugin return Stream.Null; } - var result = process.StandardOutput.BaseStream; + var source = process.StandardOutput.BaseStream; + + var buffer = BufferManager.GetStream(); + + try + { + await source.CopyToAsync(buffer, token); + } + catch (OperationCanceledException) + { + await buffer.DisposeAsync(); + throw; + } + + buffer.Seek(0, SeekOrigin.Begin); token.ThrowIfCancellationRequested(); @@ -245,7 +276,7 @@ namespace Flow.Launcher.Core.Plugin return Stream.Null; } - return result; + return buffer; } catch (Exception e) {