コード例 #1
0
        public async Task AddFxbFxpFiles(List <string> files)
        {
            List <(string fileName, string reason)> failedFiles = new List <(string, string)>();

            foreach (var filename in files)
            {
                var result = VstUtils.LoadFxp(filename, Plugin.PluginInfo.ToNonSurrogate());

                if (result.result == VstUtils.LoadFxpResult.Error)
                {
                    failedFiles.Add((filename, result.message));
                }
                else
                {
                    AddBankFile(filename);
                }
            }

            if (failedFiles.Count > 0)
            {
                var sb = new StringBuilder();
                sb.AppendLine("The following FXB/FXP files could not be added:");
                sb.AppendLine();

                foreach (var fail in failedFiles)
                {
                    sb.AppendLine($"{fail.fileName}: {fail.reason}");
                    sb.AppendLine();
                }

                await _messageService.ShowErrorAsync(sb.ToString(), "Unable to add some FXB/FXP files",
                                                     HelpLinks.SETTINGS_PLUGIN_FXBFXPNOTES);
            }
        }
コード例 #2
0
        public Guid RegisterPlugin(string dllPath, bool backgroundProcessing = true)
        {
            App.Ping();
            var guid    = Guid.NewGuid();
            var logFile = VstUtils.GetWorkerPluginLog(Process.GetCurrentProcess().Id, guid);

            var plugin = new RemoteVstPlugin
            {
                DllPath = dllPath, BackgroundProcessing = backgroundProcessing,
                Logger  = new MiniDiskLogger(logFile)
            };

            _plugins.Add(guid, plugin);

            return(guid);
        }
コード例 #3
0
        private string GetUserContentDirectory()
        {
            string userContentDirectory;

            if (!Directory.Exists(UserContentDirectory))
            {
                userContentDirectory = VstUtils.GetDefaultNativeInstrumentsUserContentDirectory();
            }
            else
            {
                userContentDirectory = UserContentDirectory;
            }

            var bankDirectory = Path.Combine(userContentDirectory, GetNKSFPluginName(PluginName),
                                             GetNKSFBankName());

            return(bankDirectory);
        }
        public VstUtils.LoadFxpResult LoadFxp(string filePath)
        {
            var result = VstUtils.LoadFxp(filePath, PluginInstance.Plugin.PluginInfo.ToNonSurrogate());

            if (result.result == VstUtils.LoadFxpResult.Error)
            {
                Logger.Error($"Error loading FXB/FXP {filePath}: {result.message}");
                return(result.result);
            }

            // If your plug-in is configured to use chunks
            // the Host will ask for a block of memory describing the current
            // plug-in state for saving.
            // To restore the state at a later stage, the same data is passed
            // back to setChunk.
            var chunkData = result.fxp.ChunkDataByteArray;

            PluginInstance.SetProgram(0);
            PluginInstance.SetChunk(chunkData, result.result == VstUtils.LoadFxpResult.Program);

            return(result.result);
        }
        protected int GetAdditionalBanksPresetCount()
        {
            var presetCount = 0;

            foreach (var bank in AdditionalBankFiles)
            {
                var result = VstUtils.LoadFxp(bank.Path, PluginInstance.Plugin.PluginInfo.ToNonSurrogate());

                if (result.result == VstUtils.LoadFxpResult.Error)
                {
                    continue;
                }

                if (result.result == VstUtils.LoadFxpResult.Program)
                {
                    presetCount++;
                }
                else if (result.result == VstUtils.LoadFxpResult.Bank)
                {
                    var ranges = bank.GetProgramRanges();

                    if (ranges.Count == 0)
                    {
                        presetCount += PluginInstance.Plugin.PluginInfo.ProgramCount;
                    }
                    else
                    {
                        foreach (var(_, length) in ranges)
                        {
                            presetCount += length;
                        }
                    }
                }
            }

            return(presetCount);
        }
コード例 #6
0
ファイル: App.xaml.cs プロジェクト: terminar/PresetMagician
        protected override void OnStartup(StartupEventArgs e)
        {
            var path = VstUtils.GetVstWorkerLogDirectory();

            var logFile = Path.Combine(path, "PresetMagician.RemoteVstHost" +
                                       Process.GetCurrentProcess().Id + ".log");

            MiniDiskLogger = new MiniDiskLogger(logFile);

            AppDomain.CurrentDomain.UnhandledException   += CurrentDomainOnUnhandledException;
            Current.DispatcherUnhandledException         += CurrentOnDispatcherUnhandledException;
            TaskScheduler.UnobservedTaskException        += TaskSchedulerOnUnobservedTaskException;
            AppDomain.CurrentDomain.FirstChanceException += CurrentDomainOnFirstChanceException;

            string address = Constants.BaseAddress + Process.GetCurrentProcess().Id;

            _serviceHost = new ServiceHost(typeof(RemoteVstService));
            var binding = WcfUtils.GetNetNamedPipeBinding();

            var dummyWin = new Window();

            Current.MainWindow = dummyWin;

            _serviceHost.AddServiceEndpoint(typeof(IRemoteVstService), binding, address);
            _serviceHost.Faulted += ServiceHostOnFaulted;
            _serviceHost.Opened  += ServiceHostOnOpened;
            _serviceHost.Open();

            _shutdownTimer           = new Timer();
            _shutdownTimer.Elapsed  += OnIdleTimeout;
            _shutdownTimer.Interval  = 60 * 2 * 1000; // 2 minutes idle timeout
            _shutdownTimer.Enabled   = true;
            _shutdownTimer.AutoReset = false;

            base.OnStartup(e);
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: terminar/PresetMagician
        public static void Main(string[] args)
        {
            FrontendInitializer.RegisterTypes(ServiceLocator.Default);
            FrontendInitializer.Initialize(ServiceLocator.Default);
            var vendorPresetParserService = ServiceLocator.Default.ResolveType <VendorPresetParserService>();
            var logger = new RollingInMemoryLogListener();

            LogManager.AddListener(logger);

            var pluginTestDirectory = @"C:\Program Files\VSTPlugins";
            var testResults         = new List <PluginTestResult>();

            var presetParserDictionary = vendorPresetParserService.GetPresetHandlerListByPlugin();


            var testData       = ReadTestData();
            var ignoredPlugins = ReadIgnoredPlugins();

            List <string> IgnoredPresetParsers = new List <string>();

            IgnoredPresetParsers.Add("VoidPresetParser");

            var localLogger = new MiniConsoleLogger();
            var hasIgnored  = false;

            localLogger.SetConsoleLogLevelFilter(new HashSet <LogLevel> {
                LogLevel.Error, LogLevel.Warning
            });

            if (args.Length > 0)
            {
                foreach (var key in presetParserDictionary.Keys.ToList())
                {
                    if (!presetParserDictionary[key].PresetParserType.ToLower().Contains(args[0].ToLower()))
                    {
                        presetParserDictionary.Remove(key);
                        hasIgnored = true;
                    }
                }
            }

            foreach (var presetParserKeyValue in presetParserDictionary)
            {
                var presetParser = presetParserKeyValue.Value;
                var pluginId     = presetParserKeyValue.Key;

                if (IgnoredPresetParsers.Contains(presetParser.PresetParserType))
                {
                    continue;
                }

                if (IsIgnored(ignoredPlugins, presetParser.PresetParserType, pluginId))
                {
                    continue;
                }

                Console.Write(presetParser.PresetParserType + ": ");

                var start = DateTime.Now;

                var pluginLocation = new PluginLocation
                {
                    DllPath = @"C:\Program Files\VstPlugins\Foobar.dll", IsPresent = true
                };

                var plugin = new Plugin
                {
                    VstPluginId = pluginId, PluginLocation = pluginLocation,
                    PluginInfo  = new VstPluginInfoSurrogate
                    {
                        ProgramCount = 1, Flags = VstPluginFlags.ProgramChunks, PluginID = pluginId
                    }
                };

                var stubProcess = new StubVstHostProcess();
                stubProcess.PluginId = pluginId;

                var remoteInstance = new RemotePluginInstance(stubProcess, plugin);

                presetParser.DataPersistence = new NullPresetPersistence();
                presetParser.PluginInstance  = remoteInstance;
                presetParser.RootBank        = plugin.RootBank.First();
                presetParser.Logger.Clear();
                presetParser.Logger.MirrorTo(localLogger);

                var testResult = new PluginTestResult
                {
                    VendorPresetParser = presetParser.PresetParserType,
                    PluginId           = plugin.VstPluginId
                };

                double timeForNumPresets = 0;
                double timeForDoScan     = 0;
                double totalTime         = 0;
                try
                {
                    presetParser.Init();
                    testResult.ReportedPresets = presetParser.GetNumPresets();
                    timeForNumPresets          = (DateTime.Now - start).TotalSeconds;
                    start = DateTime.Now;
                    presetParser.DoScan().GetAwaiter().GetResult();
                    timeForDoScan = (DateTime.Now - start).TotalSeconds;
                    totalTime     = timeForNumPresets + timeForDoScan;
                }
                catch (Exception e)
                {
                    testResult.Error = "Errored";
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.StackTrace);
                }

                testResult.Presets = plugin.Presets.Count;

                var timePerPreset = (totalTime / testResult.Presets) * 1000;
                // ReSharper disable once LocalizableElement
                Console.WriteLine(
                    $"{testResult.Presets} parsed in {totalTime:F3}s (avg {timePerPreset:F3}ms / Preset, DoScan {timeForDoScan:F3}s, NumPresets {timeForNumPresets:F3}s");

                var testDataEntries    = GetTestDataEntries(testData, presetParser.PresetParserType, pluginId);
                var hasTestDataEntries = testDataEntries.Count > 0;
                var testDataOk         = true;
                foreach (var preset in plugin.Presets)
                {
                    if (preset.Metadata.BankPath == "")
                    {
                        testResult.BankMissing++;
                    }

                    foreach (var testDataEntry in testDataEntries.ToList())
                    {
                        if (preset.Metadata.PresetName == testDataEntry.ProgramName &&
                            preset.Metadata.BankPath == testDataEntry.BankPath)
                        {
                            var testFilename = PathUtils.SanitizeFilename(
                                testDataEntry.PresetParser + "." + preset.OriginalMetadata.PresetName +
                                ".testdata");
                            var myDocumentsTestDataFile = Path.Combine(GetPatchFilesDirectory(), testFilename);
                            var localTestDataFile       = Path.Combine("TestData", testFilename);


                            var presetHash = testDataEntry.Hash.TrimEnd();
                            if (preset.PresetHash != presetHash)
                            {
                                var fileMessage     = "";
                                var wrongPresetData = myDocumentsTestDataFile + ".wrong";
                                testDataOk = false;

                                if (File.Exists(myDocumentsTestDataFile))
                                {
                                    fileMessage = $"Original preset data in {myDocumentsTestDataFile}" +
                                                  Environment.NewLine +
                                                  $"Current (wrong) preset data in {wrongPresetData}";
                                }
                                else
                                {
                                    fileMessage =
                                        $"Original preset data not found (expected in {myDocumentsTestDataFile})" +
                                        Environment.NewLine +
                                        $"Current (wrong) preset data in {wrongPresetData}";
                                }

                                File.WriteAllBytes(wrongPresetData, LZ4Pickler.Unpickle(
                                                       NullPresetPersistence.PresetData[preset.OriginalMetadata.SourceFile]));
                                testResult.DetailedErrors.Add(
                                    $"Found preset {testDataEntry.ProgramName} with bank path " +
                                    $"{testDataEntry.BankPath} but the preset hashes were different. " +
                                    $"Expected hash {presetHash} but found hash {preset.PresetHash}" +
                                    Environment.NewLine + Environment.NewLine + $"{fileMessage}");
                            }
                            else
                            {
                                // Check if the file exists in the output directory
                                if (!File.Exists(myDocumentsTestDataFile))
                                {
                                    if (File.Exists(localTestDataFile))
                                    {
                                        File.Copy(localTestDataFile, myDocumentsTestDataFile);
                                    }
                                    else
                                    {
                                        File.WriteAllBytes(myDocumentsTestDataFile,
                                                           LZ4Pickler.Unpickle(
                                                               NullPresetPersistence.PresetData[preset.OriginalMetadata.SourceFile]));
                                    }
                                }
                                else
                                {
                                    if (!File.Exists(localTestDataFile))
                                    {
                                        testResult.DetailedErrors.Add(
                                            $"Warning: The preset data file {testFilename} exists in the documents " +
                                            "folder but not in the source folder. Copy from documents to git folder. " +
                                            "If already done, remember to clean the presetparsertest project.");
                                    }
                                }

                                var hash = HashUtils.getIxxHash(File.ReadAllBytes(myDocumentsTestDataFile));

                                if (hash != presetHash)
                                {
                                    testResult.DetailedErrors.Add(
                                        $"Warning: The preset data file {myDocumentsTestDataFile} exists but does not match the " +
                                        $"preset hash from the reference presets. Expected: {testDataEntry.Hash} found {hash}");
                                }
                            }

                            testDataEntries.Remove(testDataEntry);
                        }
                    }
                }

                if (testDataEntries.Count > 0)
                {
                    foreach (var missingTestDataEntry in testDataEntries)
                    {
                        var presetHash = missingTestDataEntry.Hash.TrimEnd();
                        testResult.DetailedErrors.Add(
                            $"Did not find preset {missingTestDataEntry.ProgramName} with bank path " +
                            $"{missingTestDataEntry.BankPath} and hash {presetHash}");
                    }

                    testResult.IsOK = false;
                }

                if (plugin.Presets.Count > 0)
                {
                    var randomPreset = plugin.Presets.OrderBy(qu => Guid.NewGuid()).First();
                    testResult.RndHash       = randomPreset.PresetHash;
                    testResult.RndPresetName = randomPreset.Metadata.PresetName;
                    testResult.RndBankPath   = randomPreset.Metadata.BankPath;
                }

                var mockFxp = Path.Combine(Directory.GetCurrentDirectory(), "mock.fxp");
                var fxp     = new FXP();
                fxp.ReadFile(Path.Combine(Directory.GetCurrentDirectory(), "test.fxp"));
                fxp.FxID = VstUtils.PluginIdNumberToIdString(pluginId);
                fxp.WriteFile(mockFxp);
                // Test additional banks
                var bankFile = new BankFile();
                bankFile.Path     = mockFxp;
                bankFile.BankName = "Default";

                plugin.AdditionalBankFiles.Clear();
                plugin.AdditionalBankFiles.Add(bankFile);

                bool additionalBankFileCountOk = false;


                if (presetParser.GetNumPresets() == testResult.ReportedPresets + 1)
                {
                    additionalBankFileCountOk = true;
                }
                else
                {
                    testResult.Error += " additionalBankFileCount failed";
                }

                plugin.Presets.Clear();
                NullPresetPersistence.PresetData.Clear();
                presetParser.DoScan().GetAwaiter().GetResult();

                var additionalBankFileScanOk = false;

                if (plugin.Presets.Count == testResult.Presets + 1)
                {
                    additionalBankFileScanOk = true;
                }
                else
                {
                    testResult.Error += " additionalBankFileScan failed";
                }

                bool bankMissingOk = false;
                if (NumBankMissingsOk.ContainsKey(testResult.PluginId))
                {
                    if (testResult.BankMissing <= NumBankMissingsOk[testResult.PluginId])
                    {
                        bankMissingOk = true;
                    }
                }
                else
                {
                    if (testResult.BankMissing < 2)
                    {
                        bankMissingOk = true;
                    }
                }

                if (hasTestDataEntries && testDataOk && testResult.Presets > 5 && bankMissingOk &&
                    testResult.Presets == testResult.ReportedPresets && additionalBankFileCountOk &&
                    additionalBankFileScanOk)
                {
                    testResult.IsOK = true;
                }

                testResults.Add(testResult);

                NullPresetPersistence.PresetData.Clear();
            }


            var consoleTable = ConsoleTable.From(from testRes in testResults
                                                 where testRes.IsOK == false
                                                 orderby testRes.Presets
                                                 select testRes);

            Console.WriteLine(consoleTable.ToMinimalString());

            foreach (var testRes in (from testRes in testResults
                                     where testRes.DetailedErrors.Count > 0
                                     orderby testRes.Presets
                                     select testRes))
            {
                Console.WriteLine(Environment.NewLine);
                Console.WriteLine($"Detailed Errors for {testRes.VendorPresetParser}");
                Console.WriteLine($"------------------------------------------------------------");

                foreach (var detailedError in testRes.DetailedErrors)
                {
                    Console.WriteLine($"Error #{testRes.DetailedErrors.IndexOf(detailedError)}: {detailedError}");
                }
            }

            Console.WriteLine($"Stuff left: {consoleTable.Rows.Count} / {presetParserDictionary.Count}");

            foreach (var data in GlobalMethodTimeLogger.GetTopMethods())
            {
                Console.WriteLine($"{data.Name}: {data.Duration.TotalSeconds.ToString()}ms");
            }

            if (hasIgnored)
            {
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
            }
        }
コード例 #8
0
 private void OnOpenVstWorkerLogDirectoryExecute()
 {
     Process.Start(Path.GetDirectoryName(VstUtils.GetVstWorkerLogDirectory()));
 }
コード例 #9
0
        protected override async void OnStartup(StartupEventArgs e)
        {
            var languageService = ServiceLocator.Default.ResolveType <ILanguageService>();

            languageService.PreferredCulture = new CultureInfo("en-US");

            languageService.FallbackCulture = new CultureInfo("en-US");

#if DEBUG
            _debugListener = LogManager.AddDebugListener(true);
#endif
            var fileLogListener = new FileLogListener
            {
                IgnoreCatelLogging = true,
                FilePath           = FileLocations.LogFile,
                TimeDisplay        = TimeDisplay.DateTime
            };
            LogManager.IgnoreDuplicateExceptionLogging = false;
            LogManager.AddListener(fileLogListener);
            LogManager.GetCurrentClassLogger().Debug($"Started with command line {Environment.CommandLine}");

            var serviceLocator = ServiceLocator.Default;
            var updateService  = serviceLocator.ResolveType <IUpdateService>();
            updateService.Initialize(Settings.Application.AutomaticUpdates.AvailableChannels,
                                     Settings.Application.AutomaticUpdates.DefaultChannel,
                                     Settings.Application.AutomaticUpdates.CheckForUpdatesDefaultValue);

            if (updateService.IsUpdateSystemAvailable)
            {
                LogManager.GetCurrentClassLogger().Debug("Update system available, processing squirrel events");
                using (var mgr = new UpdateManager(updateService.CurrentChannel.DefaultUrl))
                {
                    // Note, in most of these scenarios, the app exits after this method
                    // completes!
                    SquirrelAwareApp.HandleEvents(
                        onInitialInstall: v =>
                    {
                        LogManager.GetCurrentClassLogger().Debug("Installing shortcuts");
                        mgr.CreateShortcutForThisExe();
                        Environment.Exit(0);
                    },
                        onAppUpdate: v =>
                    {
                        LogManager.GetCurrentClassLogger().Debug("Update: Installing shortcuts");
                        mgr.CreateShortcutForThisExe();
                        Environment.Exit(0);
                    },
                        onAppUninstall: v =>
                    {
                        mgr.RemoveShortcutForThisExe();
                        Environment.Exit(0);
                    });
                }
            }


            LogManager.GetCurrentClassLogger().Debug("Startup");

            try
            {
                RotateLogFile(fileLogListener.FilePath);
            }
            catch (Exception exception)
            {
                LogManager.GetCurrentClassLogger().Error("Tried to rotate the log file, but it failed.");
                LogManager.GetCurrentClassLogger().Error(exception);
                MessageBox.Show(
                    $"Unable to rotate the log file {fileLogListener.FilePath}. Please verify that you have access to that file. " +
                    $"We will continue, but no logging will be available. Additional information: {Environment.NewLine}{Environment.NewLine}{exception}",
                    "Log File Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
            }

            // Clean up old RemoteVstHost logs
            VstUtils.CleanupVstWorkerLogDirectory();

            await StartShell();
        }
コード例 #10
0
        public List <PluginInfoItem> GetPluginInfoItems(IVstPluginContext pluginContext)
        {
            var pluginInfoItems = new List <PluginInfoItem>();

            if (pluginContext == null)
            {
                return(pluginInfoItems);
            }

            // plugin product
            pluginInfoItems.Add(new PluginInfoItem("Base", "Plugin Name",
                                                   pluginContext.PluginCommandStub.GetEffectName()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Product",
                                                   pluginContext.PluginCommandStub.GetProductString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Vendor",
                                                   pluginContext.PluginCommandStub.GetVendorString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Vendor Version",
                                                   pluginContext.PluginCommandStub.GetVendorVersion().ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Vst Support",
                                                   pluginContext.PluginCommandStub.GetVstVersion().ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Plugin Category",
                                                   pluginContext.PluginCommandStub.GetCategory().ToString()));

            // plugin info
            pluginInfoItems.Add(new PluginInfoItem("Base", "Flags", pluginContext.PluginInfo.Flags.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Plugin ID",
                                                   pluginContext.PluginInfo.PluginID.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Plugin ID String",
                                                   VstUtils.PluginIdNumberToIdString(pluginContext.PluginInfo.PluginID)));

            pluginInfoItems.Add(new PluginInfoItem("Base", "Plugin Version",
                                                   pluginContext.PluginInfo.PluginVersion.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Audio Input Count",
                                                   pluginContext.PluginInfo.AudioInputCount.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Audio Output Count",
                                                   pluginContext.PluginInfo.AudioOutputCount.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Initial Delay",
                                                   pluginContext.PluginInfo.InitialDelay.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Program Count",
                                                   pluginContext.PluginInfo.ProgramCount.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Parameter Count",
                                                   pluginContext.PluginInfo.ParameterCount.ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Base", "Tail Size",
                                                   pluginContext.PluginCommandStub.GetTailSize().ToString()));

            // can do
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.Bypass),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.Bypass)).ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.MidiProgramNames),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.MidiProgramNames))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.Offline),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.Offline)).ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.ReceiveVstEvents),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.ReceiveVstEvents))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.ReceiveVstMidiEvent),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.ReceiveVstMidiEvent))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.ReceiveVstTimeInfo),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.ReceiveVstTimeInfo))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.SendVstEvents),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.SendVstEvents))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.SendVstMidiEvent),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.SendVstMidiEvent))
                                                   .ToString()));

            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.ConformsToWindowRules),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.ConformsToWindowRules))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.Metapass),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.Metapass))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.MixDryWet),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.MixDryWet))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.Multipass),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.Multipass))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.NoRealTime),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.NoRealTime))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.PlugAsChannelInsert),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.PlugAsChannelInsert))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.PlugAsSend),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.PlugAsSend))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.SendVstTimeInfo),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.SendVstTimeInfo))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x1in1out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x1in1out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x1in2out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x1in2out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x2in1out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x2in1out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x2in2out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x2in2out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x2in4out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x2in4out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x4in2out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x4in2out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x4in4out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x4in4out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x4in8out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x4in8out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x8in4out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x8in4out))
                                                   .ToString()));
            pluginInfoItems.Add(new PluginInfoItem("CanDo", nameof(VstPluginCanDo.x8in8out),
                                                   pluginContext.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.x8in8out))
                                                   .ToString()));

            pluginInfoItems.Add(new PluginInfoItem("Program", "Current Program Index",
                                                   pluginContext.PluginCommandStub.GetProgram().ToString()));
            pluginInfoItems.Add(new PluginInfoItem("Program", "Current Program Name",
                                                   pluginContext.PluginCommandStub.GetProgramName()));

            return(pluginInfoItems);
        }