UpdateMetadata(IList <Plugin> pluginsToUpdate, ApplicationProgress applicationProgress) { var pluginsToRemove = new List <Plugin>(); var mergedPlugins = new List <(Plugin oldPlugin, Plugin mergedIntoPlugin)>(); var progressStatus = new CountProgress(pluginsToUpdate.Count); foreach (var plugin in pluginsToUpdate) { if (applicationProgress.CancellationToken.IsCancellationRequested) { return(pluginsToRemove, mergedPlugins); } try { _globalFrontendService.SelectedPlugin = plugin; progressStatus.Current = pluginsToUpdate.IndexOf(plugin); progressStatus.Status = $"Loading metadata for {plugin.DllFilename}"; applicationProgress.Progress.Report(progressStatus); var originalPluginLocation = plugin.PluginLocation; foreach (var pluginLocation in plugin.PluginLocations) { if (pluginLocation.IsPresent && plugin.RequiresMetadataScan /*pluginLocation.LastMetadataAnalysisVersion != _globalService.PresetMagicianVersion && * (!pluginLocation.HasMetadata || plugin.RequiresMetadataScan || pluginLocation.PresetParser == null || (pluginLocation.PresetParser != null && * pluginLocation.PresetParser.RequiresRescan()))*/) { plugin.PluginLocation = pluginLocation; pluginLocation.LastMetadataAnalysisVersion = _globalService.PresetMagicianVersion; using (var remotePluginInstance = _remoteVstService.GetRemotePluginInstance(plugin, false)) { try { await remotePluginInstance.LoadPlugin(); plugin.Logger.Debug($"Attempting to find presetParser for {plugin.PluginName}"); pluginLocation.PresetParser = null; _vendorPresetParserService.DeterminatePresetParser(remotePluginInstance); remotePluginInstance.UnloadPlugin(); } catch (Exception e) { applicationProgress.LogReporter.Report(new LogEntry(LogLevel.Error, $"Error while loading metadata for {plugin.DllPath}: {e.GetType().FullName} {e.Message}")); LogTo.Debug(e.StackTrace); } } } } plugin.PluginLocation = originalPluginLocation; plugin.EnsurePluginLocationIsPresent(); plugin.UpdateRequiresMetadataScanFlag(_globalService.PresetMagicianVersion); if (!plugin.HasMetadata && plugin.PluginLocation == null && plugin.Presets.Count == 0) { // No metadata and still no plugin location dll => remove it applicationProgress.LogReporter.Report(new LogEntry(LogLevel.Info, "Removing unknown plugin entry without metadata, without presets and without plugin dll")); pluginsToRemove.Add(plugin); continue; } if (!plugin.HasMetadata) { // Still no metadata, probably plugin loading failure. Try again in the next version. continue; } if (_globalService.RuntimeConfiguration.StripBridgedPluginPrefix && plugin.PluginName.StartsWith("[jBridge]")) { plugin.OverridePluginName = true; plugin.OverriddenPluginName = plugin.PluginName.Replace("[jBridge]", ""); } // We now got metadata - check if there's an existing plugin with the same plugin ID. If so, // merge this plugin with the existing one if it has no presets. var existingPlugin = (from p in _globalService.Plugins where p.VstPluginId == plugin.VstPluginId && p.PluginId != plugin.PluginId && plugin.IsPresent && !pluginsToRemove.Contains(p) select p) .FirstOrDefault(); if (existingPlugin == null) { continue; } if (plugin.Presets.Count == 0) { // There's an existing plugin which this plugin can be merged into. Schedule it for removal pluginsToRemove.Add(plugin); mergedPlugins.Add((oldPlugin: plugin, mergedIntoPlugin: existingPlugin)); if (existingPlugin.PluginLocation == null) { if (Core.UseDispatcher) { await _dispatcherService.InvokeAsync(() => { existingPlugin.PluginLocation = plugin.PluginLocation; }); } else { existingPlugin.PluginLocation = plugin.PluginLocation; } } else { existingPlugin.PluginLocations.Add(plugin.PluginLocation); existingPlugin.EnsurePluginLocationIsPresent(); } } else if (existingPlugin.Presets.Count == 0) { // The existing plugin has no presets - remove it! pluginsToRemove.Add(existingPlugin); mergedPlugins.Add((oldPlugin: existingPlugin, mergedIntoPlugin: plugin)); if (plugin.PluginLocation == null) { if (Core.UseDispatcher) { await _dispatcherService.InvokeAsync(() => { plugin.PluginLocation = existingPlugin.PluginLocation; }); } else { plugin.PluginLocation = existingPlugin.PluginLocation; } } else { plugin.PluginLocations.Add(existingPlugin.PluginLocation); existingPlugin.EnsurePluginLocationIsPresent(); } } } catch (Exception e) { applicationProgress.LogReporter.Report(new LogEntry(LogLevel.Error, $"Unable to load metadata for {plugin.DllFilename} because of {e.GetType().FullName} {e.Message}")); } await _dispatcherService.InvokeAsync(() => { plugin.NativeInstrumentsResource.Load(plugin); }); } return(pluginsToRemove, mergedPlugins); }