From e320ca1d492594351d81f05ab3da8838c8672dd6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 1 Feb 2025 13:10:32 +0800 Subject: [PATCH 01/10] Add support for deleting plugin settings when uninstalling plugins --- Flow.Launcher.Core/Plugin/PluginManager.cs | 21 +++++++++++++++---- .../Languages/en.xaml | 6 ++++-- .../Languages/zh-cn.xaml | 6 ++++-- .../Languages/zh-tw.xaml | 6 ++++-- .../PluginsManager.cs | 6 +++++- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 5c4eaa1dadc..55bc0e2bddb 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -14,6 +14,7 @@ using Flow.Launcher.Plugin.SharedCommands; using System.Text.Json; using Flow.Launcher.Core.Resource; +using Flow.Launcher.Infrastructure.Storage; namespace Flow.Launcher.Core.Plugin { @@ -439,7 +440,7 @@ public static bool PluginModified(string uuid) public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath) { InstallPlugin(newVersion, zipFilePath, checkModified:false); - UninstallPlugin(existingVersion, removeSettings:false, checkModified:false); + UninstallPlugin(existingVersion, removeSettings:false, removePluginSettings:false, checkModified: false); _modifiedPlugins.Add(existingVersion.ID); } @@ -454,9 +455,9 @@ public static void InstallPlugin(UserPlugin plugin, string zipFilePath) /// /// Uninstall a plugin. /// - public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true) + public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true, bool removePluginSettings = false) { - UninstallPlugin(plugin, removeSettings, true); + UninstallPlugin(plugin, removeSettings, removePluginSettings, true); } #endregion @@ -529,7 +530,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c } } - internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool checkModified) + internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool removePluginSettings, bool checkModified) { if (checkModified && PluginModified(plugin.ID)) { @@ -542,6 +543,18 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID); } + if (removePluginSettings) + { + var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath); + var assembly = assemblyLoader.LoadAssemblyAndDependencies(); + var assemblyName = assembly.GetName().Name; + var directoryPath = Path.Combine(DataLocation.DataDirectory(), JsonStorage.DirectoryName, Constant.Plugins, assemblyName); + if (Directory.Exists(directoryPath)) + { + Directory.Delete(directoryPath, true); + } + } + // Marked for deletion. Will be deleted on next start up using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index de6a3a2fb4c..573ca90519e 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -15,6 +15,8 @@ Installing Plugin Download and install {0} Plugin Uninstall + Keep plugin settings + Do you want to keep the settings of the plugin for the next usage? Plugin {0} successfully installed. Restarting Flow, please wait... Unable to find the plugin.json metadata file from the extracted zip file. Error: A plugin which has the same or greater version with {0} already exists. @@ -37,13 +39,13 @@ Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) - + Plugin {0} successfully installed. Please restart Flow. Plugin {0} successfully uninstalled. Please restart Flow. Plugin {0} successfully updated. Please restart Flow. {0} plugins successfully updated. Please restart Flow. Plugin {0} has already been modified. Please restart Flow before making any further changes. - + Plugins Manager Management of installing, uninstalling or updating Flow Launcher plugins diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml index 676c20a734d..033bfed9489 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml @@ -13,6 +13,8 @@ 正在安装插件 下载与安装 {0} 插件卸载 + 保留插件设置 + 你希望保留插件设置以便于下次使用吗? 插件安装成功。正在重新启动 Flow Launcher,请稍候... 安装失败:无法从新插件中找到plugin.json元数据文件 错误:具有相同或更高版本的 {0} 的插件已经存在。 @@ -35,13 +37,13 @@ 插件{0}更新成功。正在重新启动 Flow Launcher,请稍候... 从未知源安装 您正在从未知源安装此插件,它可能包含潜在风险!{0}{0}请确保您了解来源以及安全性。{0}{0}您想要继续吗?{0}{0}(您可以通过设置关闭此警告) - + 成功安装插件{0}。请重新启动 Flow Launcher。 成功卸载插件{0}。请重新启动 Flow Launcher。 成功更新插件{0}。请重新启动 Flow Launcher。 插件 {0} 更新成功。请重新启动 Flow Launcher。 插件 {0} 已被修改。请在进行任何进一步更改之前重新启动Flow。 - + 插件管理 安装,卸载或更新 Flow Launcher 插件 diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml index ae37579dc32..c2497b70b1e 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml @@ -13,6 +13,8 @@ Installing Plugin 下載並安裝 {0} 解除安裝擴充功能 + 保留插件設置 + 你希望保留插件設置以便於下次使用嗎? 外掛安裝成功。正在重啟 Flow,請稍後... Unable to find the plugin.json metadata file from the extracted zip file. Error: A plugin which has the same or greater version with {0} already exists. @@ -35,13 +37,13 @@ Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) - + Plugin {0} successfully installed. Please restart Flow. Plugin {0} successfully uninstalled. Please restart Flow. Plugin {0} successfully updated. Please restart Flow. {0} plugins successfully updated. Please restart Flow. Plugin {0} has already been modified. Please restart Flow before making any further changes. - + 擴充功能管理 Management of installing, uninstalling or updating Flow Launcher plugins diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 305d248d3e8..fe3b9d3f238 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -682,7 +682,11 @@ private void Uninstall(PluginMetadata plugin) { try { - PluginManager.UninstallPlugin(plugin, removeSettings: true); + var removePluginSettings = Context.API.ShowMsgBox( + Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_subtitle"), + Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_title"), + button: MessageBoxButton.YesNo) == MessageBoxResult.No; + PluginManager.UninstallPlugin(plugin, removeSettings: true, removePluginSettings: removePluginSettings); } catch (ArgumentException e) { From 0e02a6f9cff393b1cfa7bec5bb70e1f60e87127a Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 6 Feb 2025 07:51:44 +0800 Subject: [PATCH 02/10] Revert changes in non-English language files --- .../Languages/zh-cn.xaml | 9 +++++---- .../Languages/zh-tw.xaml | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml index 033bfed9489..e6be9069d99 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml @@ -1,5 +1,8 @@ - - + + 正在下载插件... @@ -13,8 +16,6 @@ 正在安装插件 下载与安装 {0} 插件卸载 - 保留插件设置 - 你希望保留插件设置以便于下次使用吗? 插件安装成功。正在重新启动 Flow Launcher,请稍候... 安装失败:无法从新插件中找到plugin.json元数据文件 错误:具有相同或更高版本的 {0} 的插件已经存在。 diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml index c2497b70b1e..9736728a760 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml @@ -1,5 +1,8 @@ - - + + 正在下載擴充功能 @@ -13,8 +16,6 @@ Installing Plugin 下載並安裝 {0} 解除安裝擴充功能 - 保留插件設置 - 你希望保留插件設置以便於下次使用嗎? 外掛安裝成功。正在重啟 Flow,請稍後... Unable to find the plugin.json metadata file from the extracted zip file. Error: A plugin which has the same or greater version with {0} already exists. From 71b79da5d433c10de38241682245add9b6858359 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 6 Feb 2025 07:53:40 +0800 Subject: [PATCH 03/10] Revert auto format --- .../Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml | 5 +---- .../Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml index e6be9069d99..f73516a56c3 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml @@ -1,8 +1,5 @@  - + 正在下载插件... diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml index 9736728a760..f1b044d2515 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml @@ -1,8 +1,5 @@  - + 正在下載擴充功能 From 7598a6aff507cfff363d94b9f225fa7f6955039e Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 6 Feb 2025 08:08:45 +0800 Subject: [PATCH 04/10] Revert auto format --- .../Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml | 2 +- .../Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml index f73516a56c3..28196e55f72 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml @@ -1,4 +1,4 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml index f1b044d2515..96155f440a1 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml @@ -1,4 +1,4 @@ - + From 1f1b31994da4ab774e9c0964de342e7129c958d8 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 6 Feb 2025 09:35:21 +0800 Subject: [PATCH 05/10] Improve argument name to avoid possible confusion --- Flow.Launcher.Core/Plugin/PluginManager.cs | 10 +++++----- .../PluginsManager.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 55bc0e2bddb..fc915bcb306 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -440,7 +440,7 @@ public static bool PluginModified(string uuid) public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath) { InstallPlugin(newVersion, zipFilePath, checkModified:false); - UninstallPlugin(existingVersion, removeSettings:false, removePluginSettings:false, checkModified: false); + UninstallPlugin(existingVersion, removePluginFromSettings:false, removePluginSettings:false, checkModified: false); _modifiedPlugins.Add(existingVersion.ID); } @@ -455,9 +455,9 @@ public static void InstallPlugin(UserPlugin plugin, string zipFilePath) /// /// Uninstall a plugin. /// - public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true, bool removePluginSettings = false) + public static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings = true, bool removePluginSettings = false) { - UninstallPlugin(plugin, removeSettings, removePluginSettings, true); + UninstallPlugin(plugin, removePluginFromSettings, removePluginSettings, true); } #endregion @@ -530,14 +530,14 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c } } - internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool removePluginSettings, bool checkModified) + internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified) { if (checkModified && PluginModified(plugin.ID)) { throw new ArgumentException($"Plugin {plugin.Name} has been modified"); } - if (removeSettings) + if (removePluginFromSettings) { Settings.Plugins.Remove(plugin.ID); AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID); diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index fe3b9d3f238..ac4f90d9218 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -686,7 +686,7 @@ private void Uninstall(PluginMetadata plugin) Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_subtitle"), Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_title"), button: MessageBoxButton.YesNo) == MessageBoxResult.No; - PluginManager.UninstallPlugin(plugin, removeSettings: true, removePluginSettings: removePluginSettings); + PluginManager.UninstallPlugin(plugin, removePluginFromSettings: true, removePluginSettings: removePluginSettings); } catch (ArgumentException e) { From 0e4cf57e9e29c401a4ff82052b128f5ebe7865b6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 8 Feb 2025 11:57:29 +0800 Subject: [PATCH 06/10] Revert blank lines --- .../Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml | 4 ++-- .../Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml index 28196e55f72..676c20a734d 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml @@ -35,13 +35,13 @@ 插件{0}更新成功。正在重新启动 Flow Launcher,请稍候... 从未知源安装 您正在从未知源安装此插件,它可能包含潜在风险!{0}{0}请确保您了解来源以及安全性。{0}{0}您想要继续吗?{0}{0}(您可以通过设置关闭此警告) - + 成功安装插件{0}。请重新启动 Flow Launcher。 成功卸载插件{0}。请重新启动 Flow Launcher。 成功更新插件{0}。请重新启动 Flow Launcher。 插件 {0} 更新成功。请重新启动 Flow Launcher。 插件 {0} 已被修改。请在进行任何进一步更改之前重新启动Flow。 - + 插件管理 安装,卸载或更新 Flow Launcher 插件 diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml index 96155f440a1..ae37579dc32 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml @@ -35,13 +35,13 @@ Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) - + Plugin {0} successfully installed. Please restart Flow. Plugin {0} successfully uninstalled. Please restart Flow. Plugin {0} successfully updated. Please restart Flow. {0} plugins successfully updated. Please restart Flow. Plugin {0} has already been modified. Please restart Flow before making any further changes. - + 擴充功能管理 Management of installing, uninstalling or updating Flow Launcher plugins From f0e74a2aa545a74591c62fcd3e67c45faeff4a75 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 8 Feb 2025 19:12:53 +0800 Subject: [PATCH 07/10] Fix issue that plugin manager will save settings for the uninstalled and settings-removed plugins --- Flow.Launcher.Core/Plugin/PluginManager.cs | 14 ++++++++++---- .../Storage/PluginJsonStorage.cs | 18 ++++++++++++++---- Flow.Launcher/PublicAPIInstance.cs | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index fc915bcb306..146718b93ac 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -14,7 +14,6 @@ using Flow.Launcher.Plugin.SharedCommands; using System.Text.Json; using Flow.Launcher.Core.Resource; -using Flow.Launcher.Infrastructure.Storage; namespace Flow.Launcher.Core.Plugin { @@ -548,10 +547,17 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath); var assembly = assemblyLoader.LoadAssemblyAndDependencies(); var assemblyName = assembly.GetName().Name; - var directoryPath = Path.Combine(DataLocation.DataDirectory(), JsonStorage.DirectoryName, Constant.Plugins, assemblyName); - if (Directory.Exists(directoryPath)) + + // if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin + // so we need to remove it from the api instance + var method = API.GetType().GetMethod("RemovePluginSettings"); + var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName }); + + // if there exists a json storage for current plugin, we need to delete the directory path + if (pluginJsonStorage != null) { - Directory.Delete(directoryPath, true); + var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory"); + deleteMethod?.Invoke(pluginJsonStorage, null); } } diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs index abe3f55b5ad..bc3900da802 100644 --- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs @@ -3,14 +3,17 @@ namespace Flow.Launcher.Infrastructure.Storage { - public class PluginJsonStorage :JsonStorage where T : new() + public class PluginJsonStorage : JsonStorage where T : new() { + // Use assembly name to check which plugin is using this storage + public readonly string AssemblyName; + public PluginJsonStorage() { // C# related, add python related below var dataType = typeof(T); - var assemblyName = dataType.Assembly.GetName().Name; - DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, assemblyName); + AssemblyName = dataType.Assembly.GetName().Name; + DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, AssemblyName); Helper.ValidateDirectory(DirectoryPath); FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}"); @@ -20,6 +23,13 @@ public PluginJsonStorage(T data) : this() { Data = data; } + + public void DeleteDirectory() + { + if (Directory.Exists(DirectoryPath)) + { + Directory.Delete(DirectoryPath, true); + } + } } } - diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index f0295cf244a..12c65018c75 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -189,6 +189,23 @@ public void LogException(string className, string message, Exception e, private readonly ConcurrentDictionary _pluginJsonStorages = new(); + public object RemovePluginSettings(string assemblyName) + { + foreach (var keyValuePair in _pluginJsonStorages) + { + var key = keyValuePair.Key; + var value = keyValuePair.Value; + var name = value.GetType().GetField("AssemblyName")?.GetValue(value)?.ToString(); + if (name == assemblyName) + { + _pluginJsonStorages.Remove(key, out var pluginJsonStorage); + return pluginJsonStorage; + } + } + + return null; + } + /// /// Save plugin settings. /// From 37837e7002307443e7b50ee7db01c0a5878c468d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 8 Feb 2025 22:59:36 +0800 Subject: [PATCH 08/10] Fix possible exception when deleting local folder --- Flow.Launcher.Core/Plugin/PluginManager.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 146718b93ac..50150a0694e 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -521,7 +521,15 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show); - Directory.Delete(tempFolderPluginPath, true); + try + { + if (Directory.Exists(tempFolderPluginPath)) + Directory.Delete(tempFolderPluginPath, true); + } + catch (Exception e) + { + Log.Exception($"|PluginManager.InstallPlugin|Failed to delete temp folder {tempFolderPluginPath}", e); + } if (checkModified) { @@ -557,7 +565,14 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro if (pluginJsonStorage != null) { var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory"); - deleteMethod?.Invoke(pluginJsonStorage, null); + try + { + deleteMethod?.Invoke(pluginJsonStorage, null); + } + catch (Exception e) + { + Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {assemblyName}", e); + } } } From 54a0f3d16523ecaa32408277dc30800537094e89 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 9 Feb 2025 10:58:09 +0800 Subject: [PATCH 09/10] Add support for delete plugin directory for non-dotnet plugins --- .../Plugin/JsonRPCPluginBase.cs | 14 ++++- Flow.Launcher.Core/Plugin/PluginManager.cs | 60 ++++++++++++------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs index f6e5e5879a0..ed8f94bcf25 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs @@ -44,8 +44,10 @@ internal abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISetting private string SettingConfigurationPath => Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml"); - private string SettingPath => Path.Combine(DataLocation.PluginSettingsDirectory, - Context.CurrentPluginMetadata.Name, "Settings.json"); + private string SettingDirectory => Path.Combine(DataLocation.PluginSettingsDirectory, + Context.CurrentPluginMetadata.Name); + + private string SettingPath => Path.Combine(SettingDirectory, "Settings.json"); public abstract List LoadContextMenus(Result selectedResult); @@ -159,5 +161,13 @@ public Control CreateSettingPanel() { return Settings.CreateSettingPanel(); } + + public void DeletePluginSettingsDirectory() + { + if (Directory.Exists(SettingDirectory)) + { + Directory.Delete(SettingDirectory, true); + } + } } } diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 50150a0694e..2bce2ba7931 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -544,38 +544,56 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro throw new ArgumentException($"Plugin {plugin.Name} has been modified"); } - if (removePluginFromSettings) - { - Settings.Plugins.Remove(plugin.ID); - AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID); - } - if (removePluginSettings) { - var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath); - var assembly = assemblyLoader.LoadAssemblyAndDependencies(); - var assemblyName = assembly.GetName().Name; + if (AllowedLanguage.IsDotNet(plugin.Language)) // for the plugin in .NET, we can use assembly loader + { + var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath); + var assembly = assemblyLoader.LoadAssemblyAndDependencies(); + var assemblyName = assembly.GetName().Name; - // if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin - // so we need to remove it from the api instance - var method = API.GetType().GetMethod("RemovePluginSettings"); - var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName }); + // if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin + // so we need to remove it from the api instance + var method = API.GetType().GetMethod("RemovePluginSettings"); + var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName }); - // if there exists a json storage for current plugin, we need to delete the directory path - if (pluginJsonStorage != null) - { - var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory"); - try + // if there exists a json storage for current plugin, we need to delete the directory path + if (pluginJsonStorage != null) { - deleteMethod?.Invoke(pluginJsonStorage, null); + var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory"); + try + { + deleteMethod?.Invoke(pluginJsonStorage, null); + } + catch (Exception e) + { + Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e); + } } - catch (Exception e) + } + else // the plugin with json prc interface + { + var pluginPair = AllPlugins.FirstOrDefault(p => p.Metadata.ID == plugin.ID); + if (pluginPair != null && pluginPair.Plugin is JsonRPCPlugin jsonRpcPlugin) { - Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {assemblyName}", e); + try + { + jsonRpcPlugin.DeletePluginSettingsDirectory(); + } + catch (Exception e) + { + Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e); + } } } } + if (removePluginFromSettings) + { + Settings.Plugins.Remove(plugin.ID); + AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID); + } + // Marked for deletion. Will be deleted on next start up using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")); From 58f8aaa8101b92318399353880811a58e8ef89b7 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 23 Feb 2025 09:29:24 +0800 Subject: [PATCH 10/10] Show message when failed to remove plugin settings & Improve code quality --- Flow.Launcher.Core/Plugin/PluginManager.cs | 8 ++++++-- Flow.Launcher/Languages/en.xaml | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 2bce2ba7931..68f95574461 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -210,9 +210,9 @@ public static async Task InitializePluginsAsync(IPublicAPI api) { var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name)); API.ShowMsg( - InternationalizationManager.Instance.GetTranslation("failedToInitializePluginsTitle"), + API.GetTranslation("failedToInitializePluginsTitle"), string.Format( - InternationalizationManager.Instance.GetTranslation("failedToInitializePluginsMessage"), + API.GetTranslation("failedToInitializePluginsMessage"), failed ), "", @@ -568,6 +568,8 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro catch (Exception e) { Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e); + API.ShowMsg(API.GetTranslation("failedToRemovePluginSettingsTitle"), + string.Format(API.GetTranslation("failedToRemovePluginSettingsMessage"), plugin.Name)); } } } @@ -583,6 +585,8 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro catch (Exception e) { Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e); + API.ShowMsg(API.GetTranslation("failedToRemovePluginSettingsTitle"), + string.Format(API.GetTranslation("failedToRemovePluginSettingsMessage"), plugin.Name)); } } } diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 4c465d61f52..a94887bf99d 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -128,7 +128,8 @@ Version Website Uninstall - + Fail to remove plugin settings + Plugins: {0} - Fail to remove plugin settings files, please remove them manually Plugin Store @@ -145,8 +146,6 @@ This plugin has been updated within the last 7 days New Update is Available - - Theme Appearance @@ -196,7 +195,6 @@ This theme supports two(light/dark) modes. This theme supports Blur Transparent Background. - Hotkey Hotkeys