Пример #1
0
        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)));
        }
Пример #2
0
        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));
        }
Пример #3
0
        /// <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);
            }
        }
Пример #4
0
        /// <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);
            }
        }
Пример #5
0
        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));
        }
Пример #6
0
        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;
        }
Пример #7
0
        /// <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();
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
 private IEnumerable <ConfigurationPageInfo> GetConfigPages(LocalPlugin plugin)
 {
     return(GetPluginPages(plugin).Select(i => new ConfigurationPageInfo(plugin.Instance, i.Item1)));
 }
Пример #10
0
        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);
            }
        }