private IEnumerable <Tuple <PluginPageInfo, IPlugin> > GetPluginPages(LocalPlugin plugin) { if (plugin.Instance is not IHasWebPages hasWebPages) { return(Enumerable.Empty <Tuple <PluginPageInfo, IPlugin> >()); } return(hasWebPages.GetPages().Select(i => new Tuple <PluginPageInfo, IPlugin>(i, plugin.Instance))); }
private bool ChangePluginState(LocalPlugin plugin, PluginStatus state) { if (plugin.Manifest.Status == state || string.IsNullOrEmpty(plugin.Path)) { // No need to save as the state hasn't changed. return(true); } plugin.Manifest.Status = state; return(SaveManifest(plugin.Manifest, plugin.Path)); }
/// <summary> /// Enables the plugin, disabling all other versions. /// </summary> /// <param name="plugin">The <see cref="LocalPlugin"/> of the plug to disable.</param> public void EnablePlugin(LocalPlugin plugin) { if (plugin == null) { throw new ArgumentNullException(nameof(plugin)); } if (ChangePluginState(plugin, PluginStatus.Active)) { // See if there is another version, and if so, supercede it. ProcessAlternative(plugin); } }
/// <summary> /// Disable the plugin. /// </summary> /// <param name="plugin">The <see cref="LocalPlugin"/> of the plug to disable.</param> public void DisablePlugin(LocalPlugin plugin) { if (plugin == null) { throw new ArgumentNullException(nameof(plugin)); } // Update the manifest on disk if (ChangePluginState(plugin, PluginStatus.Disabled)) { // If there is another version, activate it. ProcessAlternative(plugin); } }
private bool DeletePlugin(LocalPlugin plugin) { // Attempt a cleanup of old folders. try { Directory.Delete(plugin.Path, true); _logger.LogDebug("Deleted {Path}", plugin.Path); } #pragma warning disable CA1031 // Do not catch general exception types catch #pragma warning restore CA1031 // Do not catch general exception types { return(false); } return(_plugins.Remove(plugin)); }
private void UpdatePluginSuperceedStatus(LocalPlugin plugin) { if (plugin.Manifest.Status != PluginStatus.Superceded) { return; } var predecessor = _plugins.OrderByDescending(p => p.Version) .FirstOrDefault(p => p.Id.Equals(plugin.Id) && p.IsEnabledAndSupported && p.Version != plugin.Version); if (predecessor != null) { return; } plugin.Manifest.Status = PluginStatus.Active; }
/// <summary> /// Initializes a new instance of the <see cref="PluginChangelogEntry"/> class. /// </summary> /// <param name="plugin">The plugin manifest.</param> public PluginChangelogEntry(LocalPlugin plugin) { this.Plugin = plugin; if (plugin.Manifest.Changelog.IsNullOrEmpty()) { throw new ArgumentException("Manifest has no changelog."); } var version = plugin.AssemblyName?.Version; version ??= plugin.Manifest.Testing ? plugin.Manifest.TestingAssemblyVersion : plugin.Manifest.AssemblyVersion; this.Version = version !.ToString(); }
/// <summary> /// Removes the plugin reference '<paramref name="plugin"/>. /// </summary> /// <param name="plugin">The plugin.</param> /// <returns>Outcome of the operation.</returns> public bool RemovePlugin(LocalPlugin plugin) { if (plugin == null) { throw new ArgumentNullException(nameof(plugin)); } if (DeletePlugin(plugin)) { ProcessAlternative(plugin); return(true); } _logger.LogWarning("Unable to delete {Path}, so marking as deleteOnStartup.", plugin.Path); // Unable to delete, so disable. if (ChangePluginState(plugin, PluginStatus.Deleted)) { ProcessAlternative(plugin); return(true); } return(false); }
private IEnumerable <ConfigurationPageInfo> GetConfigPages(LocalPlugin plugin) { return(GetPluginPages(plugin).Select(i => new ConfigurationPageInfo(plugin.Instance, i.Item1))); }
private IPlugin?CreatePluginInstance(Type type) { // Find the record for this plugin. var plugin = GetPluginByAssembly(type.Assembly); if (plugin?.Manifest.Status < PluginStatus.Active) { return(null); } try { _logger.LogDebug("Creating instance of {Type}", type); var instance = (IPlugin)ActivatorUtilities.CreateInstance(_appHost.ServiceProvider, type); if (plugin == null) { // Create a dummy record for the providers. // TODO: remove this code, if all provided have been released as separate plugins. plugin = new LocalPlugin( instance.AssemblyFilePath, true, new PluginManifest { Id = instance.Id, Status = PluginStatus.Active, Name = instance.Name, Version = instance.Version.ToString() }) { Instance = instance }; _plugins.Add(plugin); plugin.Manifest.Status = PluginStatus.Active; } else { plugin.Instance = instance; var manifest = plugin.Manifest; var pluginStr = instance.Version.ToString(); bool changed = false; if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal) || manifest.Id != instance.Id) { // If a plugin without a manifest failed to load due to an external issue (eg config), // this updates the manifest to the actual plugin values. manifest.Version = pluginStr; manifest.Name = plugin.Instance.Name; manifest.Description = plugin.Instance.Description; manifest.Id = plugin.Instance.Id; changed = true; } changed = changed || manifest.Status != PluginStatus.Active; manifest.Status = PluginStatus.Active; if (changed) { SaveManifest(manifest, plugin.Path); } } _logger.LogInformation("Loaded plugin: {PluginName} {PluginVersion}", plugin.Name, plugin.Version); return(instance); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { _logger.LogError(ex, "Error creating {Type}", type.FullName); if (plugin != null) { if (ChangePluginState(plugin, PluginStatus.Malfunctioned)) { _logger.LogInformation("Plugin {Path} has been disabled.", plugin.Path); return(null); } } _logger.LogDebug("Unable to auto-disable."); return(null); } }