Как получить ShellSettingsManager в расширении asyn c для VS2019? - PullRequest
1 голос
/ 27 февраля 2020

Я хотел создать небольшое расширение, чтобы добавить список внешних инструментов в VS2019. В результате быстрого поиска был найден идеальный пример кода https://docs.microsoft.com/en-us/visualstudio/extensibility/writing-to-the-user-settings-store?view=vs-2019. Это добавляет команду для вызова Блокнота, поэтому я подумал, что с некоторыми изменениями моя работа была завершена.

Однако этот пример записан как синхронное расширение, которое устарело, поэтому я попытался поместить код, предназначенный для MenuItemCallBack в метод Execute расширения, но строка

SettingsManager settingsManager = new ShellSettingsManager(ServiceProvider);

не может быть скомпилирована, поскольку ServiceProvider теперь имеет тип IAsyncServiceProvider, а конструктор ShellSettingsManager требует аргумент типа IServiceProvider.

Пока что Как я могу сказать, ShellSettingsManager все еще является способом доступа к хранилищу настроек, но все примеры, которые я смог найти, относятся к размещению кода в MenuItemCallback (а также к тому, что ему несколько лет), так что для синхронных расширений.

Итак, кто-то может подсказать мне рекомендуемый способ получения доступа к хранилищу настроек в асинхронном расширении?

1 Ответ

2 голосов
/ 12 марта 2020

Конструктор ShellSettingsManager принимает либо интерфейс IServiceProvider, либо интерфейс IVsSettings. Учитывая, что ваш производный объект AsyncPackage реализует IServiceProvider, вы должны иметь возможность просто передать его в качестве аргумента вашему конструктору. У меня работал следующий быстрый демонстрационный пакет:

using System;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft;
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.Settings;
using Task = System.Threading.Tasks.Task;

namespace UserSettingsDemo
{
    [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
    [Guid(UserSettingsDemoPackage.PackageGuidString)]
    [ProvideMenuResource("Menus.ctmenu", 1)]
    public sealed class UserSettingsDemoPackage : AsyncPackage
    {
        public const string PackageGuidString = "cff6cdea-21d1-4736-b5ea-6736624e718f";
        public static readonly Guid CommandSet = new Guid("dde1417d-ae0d-46c4-8c84-31883dc1a835");
        public const int ListExternalToolsCommand = 0x0100;

        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
        {
            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            OleMenuCommandService commandService = await GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
            Assumes.Present(commandService);
            var menuItem = new MenuCommand(OnListExternalTools, new CommandID(CommandSet, ListExternalToolsCommand));
            commandService.AddCommand(menuItem);
        }

        private void OnListExternalTools(object sender, EventArgs e)
        {
            ShellSettingsManager settingsManager = new ShellSettingsManager(this);
            WritableSettingsStore userSettingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);

            int toolCount = userSettingsStore.GetInt32("External Tools", "ToolNumKeys");
            for (int i = 0; i < toolCount; i++)
            {
                string tool = userSettingsStore.GetString("External Tools", "ToolCmd" + i);
                VsShellUtilities.ShowMessageBox(this, tool, "External Tools", OLEMSGICON.OLEMSGICON_INFO,
                    OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
            }
        }
    }
}

С уважением

...