From 4ea1ee0c043335cce3b5fd1b82058b2ca25dcdad Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 23 Oct 2022 20:05:12 +1100 Subject: [PATCH 01/31] add Node.js environment setup --- .../ExternalPlugins/PluginEnvironment.cs | 216 ++++++++++++++++++ Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- Flow.Launcher.Core/Plugin/NodePlugin.cs | 33 +++ Flow.Launcher.Core/Plugin/PluginsLoader.cs | 16 +- Flow.Launcher.Infrastructure/Constant.cs | 3 +- .../UserSettings/PluginSettings.cs | 7 +- Flow.Launcher.Plugin/AllowedLanguage.cs | 44 ++-- 7 files changed, 294 insertions(+), 27 deletions(-) create mode 100644 Flow.Launcher.Core/ExternalPlugins/PluginEnvironment.cs create mode 100644 Flow.Launcher.Core/Plugin/NodePlugin.cs diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/PluginEnvironment.cs new file mode 100644 index 00000000000..da24ad87f88 --- /dev/null +++ b/Flow.Launcher.Core/ExternalPlugins/PluginEnvironment.cs @@ -0,0 +1,216 @@ +using Droplex; +using Flow.Launcher.Core.Plugin; +using Flow.Launcher.Infrastructure; +using Flow.Launcher.Infrastructure.Logger; +using Flow.Launcher.Infrastructure.UserSettings; +using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedCommands; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Flow.Launcher.Core.ExternalPlugins +{ + internal class PluginEnvironment + { + private const string PythonExecutable = "pythonw.exe"; + + private const string NodeExecutable = "node.exe"; + + private const string PythonEnv = "Python"; + + private const string NodeEnv = "Node.js"; + + private List pluginMetadataList; + + private PluginsSettings pluginSettings; + + internal PluginEnvironment(List pluginMetadataList, PluginsSettings pluginSettings) + { + this.pluginMetadataList = pluginMetadataList; + this.pluginSettings = pluginSettings; + } + //TODO: CHECK IF NEED TO RESET PATH AFTER FLOW UPDATE + // LOG NODE PATH + internal IEnumerable PythonSetup() + { + return Setup(AllowedLanguage.Python, PythonEnv); + } + + internal IEnumerable TypeScriptSetup() + { + return Setup(AllowedLanguage.TypeScript, NodeEnv); + } + + internal IEnumerable JavaScriptSetup() + { + return Setup(AllowedLanguage.JavaScript, NodeEnv); + } + + private IEnumerable Setup(string languageType, string environment) + { + if (!pluginMetadataList.Any(o => o.Language.Equals(languageType, StringComparison.OrdinalIgnoreCase))) + return new List(); + + var envFilePath = string.Empty; + + switch (languageType) + { + case AllowedLanguage.Python: + if (!string.IsNullOrEmpty(pluginSettings.PythonDirectory) && FilesFolders.LocationExists(pluginSettings.PythonDirectory)) + return SetPathForPluginPairs($"{pluginSettings.PythonDirectory}\\{PythonExecutable}", languageType); + break; + + case AllowedLanguage.TypeScript: + case AllowedLanguage.JavaScript: + if (!string.IsNullOrEmpty(pluginSettings.NodeFilePath) && FilesFolders.FileExists(pluginSettings.NodeFilePath)) + return SetPathForPluginPairs(pluginSettings.NodeFilePath, languageType); + break; + + default: + break; + } + + if (MessageBox.Show($"Flow detected you have installed {languageType} plugins, which " + + $"will require {environment} to run. Would you like to download {environment}? " + + Environment.NewLine + Environment.NewLine + + "Click no if it's already installed, " + + $"and you will be prompted to select the folder that contains the {environment} executable", + string.Empty, MessageBoxButtons.YesNo) == DialogResult.No) + { + var dlg = new OpenFileDialog + { + InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + Multiselect = false, + CheckFileExists = true, + CheckPathExists = true, + Title = $"Please select the {environment} executable" + }; + + var result = dlg.ShowDialog(); + if (result == DialogResult.OK) + { + switch (languageType) + { + case AllowedLanguage.Python: + Constant.PythonPath = dlg.FileName; + pluginSettings.PythonDirectory = Constant.PythonPath; + break; + case AllowedLanguage.TypeScript: + case AllowedLanguage.JavaScript: + Constant.NodePath = dlg.FileName; + pluginSettings.NodeFilePath = Constant.NodePath; + break; + default: + break; + } + } + else + { + InstallEnvironment(languageType); + } + } + else + { + InstallEnvironment(languageType); + } + + switch (languageType) + { + case AllowedLanguage.Python when FilesFolders.FileExists(Constant.PythonPath) && !string.IsNullOrEmpty(pluginSettings.PythonDirectory): + return SetPathForPluginPairs(Constant.PythonPath, languageType); + + case AllowedLanguage.TypeScript when FilesFolders.FileExists(Constant.NodePath) && !string.IsNullOrEmpty(pluginSettings.NodeFilePath): + case AllowedLanguage.JavaScript when FilesFolders.FileExists(Constant.NodePath) && !string.IsNullOrEmpty(pluginSettings.NodeFilePath): + return SetPathForPluginPairs(pluginSettings.NodeFilePath, languageType); + + default: + MessageBox.Show( + "Unable to set Python executable path, please try from Flow's settings (scroll down to the bottom)."); + Log.Error("PluginsLoader", + $"Not able to successfully set Python path, the PythonDirectory variable is still an empty string.", + "PythonPlugins"); + + return new List(); + } + } + + private void InstallEnvironment(string languageType) + { + switch (languageType) + { + case AllowedLanguage.Python: + var pythonDirPath = Path.Combine(DataLocation.DataDirectory(), "PythonEmbeddable"); + FilesFolders.RemoveFolderIfExists(pythonDirPath); + + // Python 3.8.9 is used for Windows 7 compatibility + DroplexPackage.Drop(App.python_3_8_9_embeddable, pythonDirPath).Wait(); + + pluginSettings.PythonDirectory = pythonDirPath; + Constant.PythonPath = Path.Combine(pythonDirPath, PythonExecutable); + + break; + + case AllowedLanguage.TypeScript: + case AllowedLanguage.JavaScript: + var nodeDirPath = Path.Combine(DataLocation.DataDirectory(), "Node"); + FilesFolders.RemoveFolderIfExists(nodeDirPath); + + DroplexPackage.Drop(App.nodejs_16_18_0, nodeDirPath).Wait(); + + Constant.NodePath = Path.Combine(nodeDirPath, $"node-v16.18.0-win-x64\\{NodeExecutable}"); + pluginSettings.NodeFilePath = Constant.NodePath; + + break; + + default: + break; + } + } + + private IEnumerable SetPathForPluginPairs(string filePath, string languageToSet) + { + var pluginPairs = new List(); + + foreach (var metadata in pluginMetadataList) { + + switch (languageToSet) + { + case AllowedLanguage.Python when metadata.Language.Equals(languageToSet, StringComparison.OrdinalIgnoreCase): + pluginPairs.Add(new PluginPair + { + Plugin = new PythonPlugin(filePath), + Metadata = metadata + }); + break; + + case AllowedLanguage.TypeScript when metadata.Language.Equals(languageToSet, StringComparison.OrdinalIgnoreCase): + pluginPairs.Add(new PluginPair + { + Plugin = new NodePlugin(filePath), + Metadata = metadata + }); + break; + + case AllowedLanguage.JavaScript when metadata.Language.Equals(languageToSet, StringComparison.OrdinalIgnoreCase): + pluginPairs.Add(new PluginPair + { + Plugin = new NodePlugin(filePath), + Metadata = metadata + }); + break; + + default: + break; + } + } + + return pluginPairs; + } + + } +} diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 7d18c467bc6..d20fa94dc20 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -53,7 +53,7 @@ - + diff --git a/Flow.Launcher.Core/Plugin/NodePlugin.cs b/Flow.Launcher.Core/Plugin/NodePlugin.cs new file mode 100644 index 00000000000..f019aceacbc --- /dev/null +++ b/Flow.Launcher.Core/Plugin/NodePlugin.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Flow.Launcher.Core.Plugin +{ + /// + /// Execution of JavaScript & TypeScript plugins + /// + internal class NodePlugin : JsonRPCPlugin + { + public override string SupportedLanguage { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public NodePlugin(string filename) + { + + } + + protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default) + { + throw new NotImplementedException(); + } + + protected override Task RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default) + { + throw new NotImplementedException(); + } + } +} diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 7521742636a..3246a021029 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using Droplex; +using Flow.Launcher.Core.ExternalPlugins; using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; @@ -22,9 +23,20 @@ public static class PluginsLoader public static List Plugins(List metadatas, PluginsSettings settings) { var dotnetPlugins = DotNetPlugins(metadatas); - var pythonPlugins = PythonPlugins(metadatas, settings); + + var pluginEnv = new PluginEnvironment(metadatas, settings); + var pythonPlugins = pluginEnv.PythonSetup(); + var tsPlugins = pluginEnv.TypeScriptSetup(); + var jsthonPlugins = pluginEnv.JavaScriptSetup(); + var executablePlugins = ExecutablePlugins(metadatas); - var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList(); + + var plugins = dotnetPlugins + .Concat(pythonPlugins) + .Concat(tsPlugins) + .Concat(jsthonPlugins) + .Concat(executablePlugins) + .ToList(); return plugins; } diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index 57b39e46e47..f06bf58e64a 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.IO; using System.Reflection; @@ -30,6 +30,7 @@ public static class Constant public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png"); public static string PythonPath; + public static string NodePath; public static readonly string QueryTextBoxIconImagePath = $"{ProgramDirectory}\\Images\\mainsearch.svg"; diff --git a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs index c06e1587dca..68409f3f971 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs @@ -1,11 +1,14 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Flow.Launcher.Plugin; namespace Flow.Launcher.Infrastructure.UserSettings { public class PluginsSettings : BaseModel { - public string PythonDirectory { get; set; } + public string PythonDirectory { get; set; } // IS FILE PATH BUT CHANGE NAME TO FILE PATH?? + + public string NodeFilePath { get; set; } + public Dictionary Plugins { get; set; } = new Dictionary(); public void UpdatePluginSettings(List metadatas) diff --git a/Flow.Launcher.Plugin/AllowedLanguage.cs b/Flow.Launcher.Plugin/AllowedLanguage.cs index 94c645d2761..d5eea4fa56b 100644 --- a/Flow.Launcher.Plugin/AllowedLanguage.cs +++ b/Flow.Launcher.Plugin/AllowedLanguage.cs @@ -1,4 +1,6 @@ -namespace Flow.Launcher.Plugin +using System; + +namespace Flow.Launcher.Plugin { /// /// Allowed plugin languages @@ -8,34 +10,32 @@ public static class AllowedLanguage /// /// Python /// - public static string Python - { - get { return "PYTHON"; } - } + public const string Python = "Python"; /// /// C# /// - public static string CSharp - { - get { return "CSHARP"; } - } + public const string CSharp = "CSharp"; /// /// F# /// - public static string FSharp - { - get { return "FSHARP"; } - } + public const string FSharp = "FSharp"; /// /// Standard .exe /// - public static string Executable - { - get { return "EXECUTABLE"; } - } + public const string Executable = "Executable"; + + /// + /// TypeScript + /// + public const string TypeScript = "TypeScript"; + + /// + /// JavaScript + /// + public const string JavaScript = "JavaScript"; /// /// Determines if this language is a .NET language @@ -44,8 +44,8 @@ public static string Executable /// public static bool IsDotNet(string language) { - return language.ToUpper() == CSharp - || language.ToUpper() == FSharp; + return language.Equals(CSharp, StringComparison.OrdinalIgnoreCase) + || language.Equals(FSharp, StringComparison.OrdinalIgnoreCase); } /// @@ -56,8 +56,10 @@ public static bool IsDotNet(string language) public static bool IsAllowed(string language) { return IsDotNet(language) - || language.ToUpper() == Python.ToUpper() - || language.ToUpper() == Executable.ToUpper(); + || language.Equals(Python, StringComparison.OrdinalIgnoreCase) + || language.Equals(Executable, StringComparison.OrdinalIgnoreCase) + || language.Equals(TypeScript, StringComparison.OrdinalIgnoreCase) + || language.Equals(JavaScript, StringComparison.OrdinalIgnoreCase); } } } From eb203c2c8bc57960003a6f82d2740b9fbfa8be6f Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 24 Oct 2022 07:41:48 +1100 Subject: [PATCH 02/31] executable plugin language check ignore case --- Flow.Launcher.Core/Plugin/PluginsLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 3246a021029..ae602b51cef 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -210,7 +210,7 @@ private static IEnumerable SetPythonPathForPluginPairs(List ExecutablePlugins(IEnumerable source) { return source - .Where(o => o.Language.ToUpper() == AllowedLanguage.Executable) + .Where(o => o.Language.Equals(AllowedLanguage.Executable, StringComparison.OrdinalIgnoreCase)) .Select(metadata => new PluginPair { Plugin = new ExecutablePlugin(metadata.ExecuteFilePath), Metadata = metadata From 7441e908958e0a60c1482103478fd351e78f28b9 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 24 Oct 2022 07:54:15 +1100 Subject: [PATCH 03/31] python language check ignore case --- Flow.Launcher.Core/Plugin/PluginsLoader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index ae602b51cef..3362f384fa4 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -27,14 +27,14 @@ public static List Plugins(List metadatas, PluginsSe var pluginEnv = new PluginEnvironment(metadatas, settings); var pythonPlugins = pluginEnv.PythonSetup(); var tsPlugins = pluginEnv.TypeScriptSetup(); - var jsthonPlugins = pluginEnv.JavaScriptSetup(); + var jsPlugins = pluginEnv.JavaScriptSetup(); var executablePlugins = ExecutablePlugins(metadatas); var plugins = dotnetPlugins .Concat(pythonPlugins) .Concat(tsPlugins) - .Concat(jsthonPlugins) + .Concat(jsPlugins) .Concat(executablePlugins) .ToList(); return plugins; @@ -122,7 +122,7 @@ public static IEnumerable DotNetPlugins(List source) public static IEnumerable PythonPlugins(List source, PluginsSettings settings) { - if (!source.Any(o => o.Language.ToUpper() == AllowedLanguage.Python)) + if (!source.Any(o => o.Language.Equals(AllowedLanguage.Python, StringComparison.OrdinalIgnoreCase))) return new List(); if (!string.IsNullOrEmpty(settings.PythonDirectory) && FilesFolders.LocationExists(settings.PythonDirectory)) @@ -199,7 +199,7 @@ public static IEnumerable PythonPlugins(List source, private static IEnumerable SetPythonPathForPluginPairs(List source, string pythonPath) => source - .Where(o => o.Language.ToUpper() == AllowedLanguage.Python) + .Where(o => o.Language.Equals(AllowedLanguage.Python, StringComparison.OrdinalIgnoreCase)) .Select(metadata => new PluginPair { Plugin = new PythonPlugin(pythonPath), From 9e55fc58541235edea18ff66acaeb50b698d1125 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 24 Oct 2022 08:47:09 +1100 Subject: [PATCH 04/31] add node plugin execution --- Flow.Launcher.Core/Plugin/NodePlugin.cs | 35 +++++++-- Flow.Launcher.Core/Plugin/PluginsLoader.cs | 87 ---------------------- Flow.Launcher.Core/Plugin/PythonPlugin.cs | 3 +- 3 files changed, 32 insertions(+), 93 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/NodePlugin.cs b/Flow.Launcher.Core/Plugin/NodePlugin.cs index f019aceacbc..6a161029bff 100644 --- a/Flow.Launcher.Core/Plugin/NodePlugin.cs +++ b/Flow.Launcher.Core/Plugin/NodePlugin.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Flow.Launcher.Plugin; namespace Flow.Launcher.Core.Plugin { @@ -13,21 +15,44 @@ namespace Flow.Launcher.Core.Plugin /// internal class NodePlugin : JsonRPCPlugin { - public override string SupportedLanguage { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + private readonly ProcessStartInfo _startInfo; + + // TODO: Remove all, not used + public override string SupportedLanguage { get; set; } = AllowedLanguage.Executable; public NodePlugin(string filename) { + _startInfo = new ProcessStartInfo + { + FileName = filename, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + } + protected override Task RequestAsync(JsonRPCRequestModel request, CancellationToken token = default) + { + _startInfo.ArgumentList[1] = request.ToString(); + return ExecuteAsync(_startInfo, token); } protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default) - { - throw new NotImplementedException(); + { + // CONTEXT MENU NOT WORKING ?? + + // since this is not static, request strings will build up in ArgumentList if index is not specified + _startInfo.ArgumentList[1] = rpcRequest.ToString(); + return Execute(_startInfo); } - protected override Task RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default) + public override async Task InitAsync(PluginInitContext context) { - throw new NotImplementedException(); + _startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath); + _startInfo.ArgumentList.Add(string.Empty); + await base.InitAsync(context); + _startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory; } } } diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 3362f384fa4..377715bdcaa 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -120,93 +120,6 @@ public static IEnumerable DotNetPlugins(List source) return plugins; } - public static IEnumerable PythonPlugins(List source, PluginsSettings settings) - { - if (!source.Any(o => o.Language.Equals(AllowedLanguage.Python, StringComparison.OrdinalIgnoreCase))) - return new List(); - - if (!string.IsNullOrEmpty(settings.PythonDirectory) && FilesFolders.LocationExists(settings.PythonDirectory)) - return SetPythonPathForPluginPairs(source, Path.Combine(settings.PythonDirectory, PythonExecutable)); - - var pythonPath = string.Empty; - - if (MessageBox.Show("Flow detected you have installed Python plugins, which " + - "will need Python to run. Would you like to download Python? " + - Environment.NewLine + Environment.NewLine + - "Click no if it's already installed, " + - "and you will be prompted to select the folder that contains the Python executable", - string.Empty, MessageBoxButtons.YesNo) == DialogResult.No - && string.IsNullOrEmpty(settings.PythonDirectory)) - { - var dlg = new FolderBrowserDialog - { - SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) - }; - - var result = dlg.ShowDialog(); - if (result == DialogResult.OK) - { - string pythonDirectory = dlg.SelectedPath; - if (!string.IsNullOrEmpty(pythonDirectory)) - { - pythonPath = Path.Combine(pythonDirectory, PythonExecutable); - if (File.Exists(pythonPath)) - { - settings.PythonDirectory = pythonDirectory; - Constant.PythonPath = pythonPath; - } - else - { - MessageBox.Show("Can't find python in given directory"); - } - } - } - } - else - { - var installedPythonDirectory = Path.Combine(DataLocation.DataDirectory(), "PythonEmbeddable"); - - // Python 3.8.9 is used for Windows 7 compatibility - DroplexPackage.Drop(App.python_3_8_9_embeddable, installedPythonDirectory).Wait(); - - pythonPath = Path.Combine(installedPythonDirectory, PythonExecutable); - if (FilesFolders.FileExists(pythonPath)) - { - settings.PythonDirectory = installedPythonDirectory; - Constant.PythonPath = pythonPath; - } - else - { - Log.Error("PluginsLoader", - $"Failed to set Python path after Droplex install, {pythonPath} does not exist", - "PythonPlugins"); - } - } - - if (string.IsNullOrEmpty(settings.PythonDirectory) || string.IsNullOrEmpty(pythonPath)) - { - MessageBox.Show( - "Unable to set Python executable path, please try from Flow's settings (scroll down to the bottom)."); - Log.Error("PluginsLoader", - $"Not able to successfully set Python path, the PythonDirectory variable is still an empty string.", - "PythonPlugins"); - - return new List(); - } - - return SetPythonPathForPluginPairs(source, pythonPath); - } - - private static IEnumerable SetPythonPathForPluginPairs(List source, string pythonPath) - => source - .Where(o => o.Language.Equals(AllowedLanguage.Python, StringComparison.OrdinalIgnoreCase)) - .Select(metadata => new PluginPair - { - Plugin = new PythonPlugin(pythonPath), - Metadata = metadata - }) - .ToList(); - public static IEnumerable ExecutablePlugins(IEnumerable source) { return source diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs index 8f7e5760af4..6a6b3352d8f 100644 --- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs +++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.IO; using System.Threading; @@ -46,6 +46,7 @@ protected override Task RequestAsync(JsonRPCRequestModel request, Cancel protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default) { + // since this is not static, request strings will build up in ArgumentList if index is not specified _startInfo.ArgumentList[2] = rpcRequest.ToString(); _startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory; // TODO: Async Action From 9b4a5926355ae524eacead03760cc419ca33759a Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 25 Oct 2022 07:59:31 +1100 Subject: [PATCH 05/31] add Node.js file path browser to Settings window --- Flow.Launcher/SettingWindow.xaml | 19 +++++++++++++++++++ Flow.Launcher/SettingWindow.xaml.cs | 23 +++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index b763330c0ab..e34d3677c71 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -921,6 +921,25 @@ + + + + + + + +