Check if plugin has been modified when installing/updating/uninstalling

This commit is contained in:
VictoriousRaptor 2023-11-11 15:05:24 +08:00
parent b7a78362bf
commit 69dad1be6c
3 changed files with 81 additions and 15 deletions

View file

@ -31,6 +31,7 @@ namespace Flow.Launcher.Core.Plugin
private static PluginsSettings Settings;
private static List<PluginMetadata> _metadatas;
private static List<string> _modifiedPlugins = new List<string>();
/// <summary>
/// Directories that will hold Flow Launcher plugin directory
@ -358,8 +359,42 @@ namespace Flow.Launcher.Core.Plugin
&& newMetadata.Version.CompareTo(x.Metadata.Version) <= 0);
}
public static void Install(UserPlugin plugin, string downloadedFilePath)
#region Public functions
public static bool PluginModified(string uuid)
{
return _modifiedPlugins.Contains(uuid);
}
public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string downloadedFilePath)
{
InstallPlugin(newVersion, downloadedFilePath, checkModified:false);
UninstallPlugin(existingVersion, removeSettings:false, checkModified:false);
_modifiedPlugins.Add(existingVersion.ID);
}
public static void InstallPlugin(UserPlugin plugin, string downloadedFilePath)
{
InstallPlugin(plugin, downloadedFilePath, true);
}
public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true)
{
UninstallPlugin(plugin, removeSettings, true);
}
#endregion
#region Internal functions
internal static void InstallPlugin(UserPlugin plugin, string downloadedFilePath, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
// Distinguish exception from installing same or less version
throw new ArgumentException($"Plugin {plugin.Name} {plugin.ID} has been modified.", nameof(plugin));
}
var tempFolderPath = Path.Combine(Path.GetTempPath(), "flowlauncher");
var tempFolderPluginPath = Path.Combine(tempFolderPath, "plugin");
@ -420,10 +455,20 @@ namespace Flow.Launcher.Core.Plugin
FilesFolders.CopyAll(pluginFolderPath, newPluginPath);
Directory.Delete(pluginFolderPath, true);
if (checkModified)
{
_modifiedPlugins.Add(plugin.ID);
}
}
public static void Uninstall(PluginMetadata plugin, bool removeSettings = true)
internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
throw new ArgumentException($"Plugin {plugin.Name} has been modified");
}
if (removeSettings)
{
Settings.Plugins.Remove(plugin.ID);
@ -432,6 +477,13 @@ namespace Flow.Launcher.Core.Plugin
// Marked for deletion. Will be deleted on next start up
using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt"));
if (checkModified)
{
_modifiedPlugins.Add(plugin.ID);
}
}
#endregion
}
}

View file

@ -20,6 +20,7 @@
<system:String x:Key="plugin_pluginsmanager_install_error_duplicate">Error: A plugin which has the same or greater version with {0} already exists.</system:String>
<system:String x:Key="plugin_pluginsmanager_install_error_title">Error installing plugin</system:String>
<system:String x:Key="plugin_pluginsmanager_install_error_subtitle">Error occurred while trying to install {0}</system:String>
<system:String x:Key="plugin_pluginsmanager_uninstall_error_title">Error uninstalling plugin</system:String>
<system:String x:Key="plugin_pluginsmanager_update_noresult_title">No update available</system:String>
<system:String x:Key="plugin_pluginsmanager_update_noresult_subtitle">All plugins are up to date</system:String>
<system:String x:Key="plugin_pluginsmanager_update_prompt">{0} by {1} {2}{3}Would you like to update this plugin? After the update Flow will automatically restart.</system:String>
@ -36,7 +37,8 @@
<system:String x:Key="plugin_pluginsmanager_install_success_no_restart">Plugin {0} successfully installed. Please restart Flow.</system:String>
<system:String x:Key="plugin_pluginsmanager_uninstall_success_no_restart">Plugin {0} successfully uninstalled. Please restart Flow.</system:String>
<system:String x:Key="plugin_pluginsmanager_update_success_no_restart">Plugin {0} successfully updated. Please restart Flow.</system:String>
<system:String x:Key="plugin_pluginsmanager_plugin_modified_error">Plugin {0} has already been modified. Please restart Flow before making any further changes.</system:String>
<!-- Plugin Infos -->
<system:String x:Key="plugin_pluginsmanager_plugin_name">Plugins Manager</system:String>
<system:String x:Key="plugin_pluginsmanager_plugin_description">Management of installing, uninstalling or updating Flow Launcher plugins</system:String>

View file

@ -239,8 +239,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
Uninstall(x.PluginExistingMetadata, false);
var downloadToFilePath = Path.Combine(DataLocation.PluginsDirectory,
$"{x.Name}-{x.NewVersion}.zip");
@ -249,7 +247,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
.ConfigureAwait(false);
Install(x.PluginNewUserPlugin, downloadToFilePath);
PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin, downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
{
@ -413,19 +411,24 @@ namespace Flow.Launcher.Plugin.PluginsManager
throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}", downloadedFilePath);
try
{
PluginManager.Install(plugin, downloadedFilePath);
PluginManager.InstallPlugin(plugin, downloadedFilePath);
}
catch(FileNotFoundException e)
catch (FileNotFoundException e)
{
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"));
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
MessageBox.Show(Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"),
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"));
}
catch(InvalidOperationException e)
catch (InvalidOperationException e)
{
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name));
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
}
catch (ArgumentException e) {
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"), plugin.Name));
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
MessageBox.Show(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name),
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"));
}
}
@ -482,9 +485,18 @@ namespace Flow.Launcher.Plugin.PluginsManager
return Search(results, search);
}
private static void Uninstall(PluginMetadata plugin, bool removeSettings = true)
private void Uninstall(PluginMetadata plugin)
{
PluginManager.Uninstall(plugin, removeSettings);
try
{
PluginManager.UninstallPlugin(plugin, removeSettings:true);
}
catch (ArgumentException e)
{
Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_error_title"),
Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"));
}
}
}
}