Как установить и получить аргументы для пользовательской команды проекта Visual Studio

Я создал специальную команду для проекта Visual Studio, и эта команда отображается при щелчке правой кнопкой мыши по проекту. Я хотел передать команде EventArgs некоторые аргументы, например путь к папке проекта. Можно ли указать аргументы команды.

Вот метод выполнения команды.

private void Execute(object sender, EventArgs e)
{
    ThreadHelper.ThrowIfNotOnUIThread();
    string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", GetType().FullName);
    string title = "Evaluate Project Command";

    // Show a message box to prove we were here
    VsShellUtilities.ShowMessageBox(
                                    package,
                                    message,
                                    title,
                                    OLEMSGICON.OLEMSGICON_INFO,
                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
}

Я хочу получить путь к файлу проекта с помощью команды EventArgs или есть ли способ это сделать?

Если вы посмотрите на справочный документ EventArgs, вы увидите, что в нем нет необходимой вам информации, DTE должен быть правильным способом, взгляните на мой ответ. :)

Bowman Zhu 07.05.2024 04:47
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

EventArgs в сигнатуре метода для выполнения команды обычно не содержит эти данные напрямую. Однако вы можете получить подробную информацию о проекте, обратившись к объекту DTE, который представляет саму среду разработки.

Взгляните на этот пример:

https://github.com/NDiiong/DevAssist/blob/3a90dbbbd42c57dd74749f01e26ba30aeac68732/src/Commands/OpenBinFolderCommand.cs#L18

Чтобы поддерживать параметры при вызове вашей команды (например, вызове команды File.OpenFile) из командного окна и предоставлении пути или имени файла; вам нужно будет создать OleMenuCommand, а не MenuCommand. Кроме того, вам нужно будет установить свойство ParametersDescription в вашей OleMenuCommand. Например:

private MultiParamCommand(AsyncPackage package, OleMenuCommandService commandService)
{
    this.package = package ?? throw new ArgumentNullException(nameof(package));
    commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

    var menuCommandID = new CommandID(CommandSet, CommandId);
    var menuItem = new OleMenuCommand(this.Execute, menuCommandID);
    menuItem.ParametersDescription = "arguments";
    menuItem.BeforeQueryStatus += BeforeQueryStatus; 
    commandService.AddCommand(menuItem);
}

Кроме того, сама команда должна быть определена в вашем .VSCT с помощью командного флага AllowParams. Например:

<Buttons>
  <Button guid = "guidAllowParamsPackageCmdSet" id = "MultiParamCommandId" priority = "0x0100" type = "Button">
    <Parent guid = "guidAllowParamsPackageCmdSet" id = "AllowParamsMenuGroup" />
    <CommandFlag>AllowParams</CommandFlag>
    <Strings>
      <ButtonText>MultiParamCommand</ButtonText>
      <CanonicalName>MultiParamCommand</CanonicalName>
    </Strings>
  </Button>
</Buttons>

Это позволит вам вызвать команду из окна командного инструмента и указать аргументы. Обратите внимание: аргументы будут переданы в метод Execute вашей команды через параметр EventArgs. Но для доступа к нему вам нужно будет преобразовать это в OleMenuCmdEventArgs. Например:

private void Execute(object sender, EventArgs e)
{
    ThreadHelper.ThrowIfNotOnUIThread();
    
    OleMenuCmdEventArgs eventArgs = (OleMenuCmdEventArgs)e;
    string message = string.Format(CultureInfo.CurrentCulture, "Arguments passed to MultiParamCommand: {0}", eventArgs.InValue);
    string title = "MultiParamCommand";

    // Show a message box to prove we were here
    VsShellUtilities.ShowMessageBox(
        this.package,
        message,
        title,
        OLEMSGICON.OLEMSGICON_INFO,
        OLEMSGBUTTON.OLEMSGBUTTON_OK,
        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
}

Искренне,

Спасибо за предложение, как установить путь к файлу для аргументов команды, я думаю, что описание параметра похоже на «ключ». Когда я щелкаю правой кнопкой мыши по узлу проекта, как мне установить путь к папке проекта для аргументов?

Naveen 13.05.2024 09:29

AllowParams действительно полезен только в том случае, если вы хотите поддерживать вызов команды из окна командного инструмента. Если вы просто хотите получить имя файла элемента, на котором вы щелкнули правой кнопкой мыши, чтобы вызвать контекстное меню, вам не нужен AllowParams. Просто используйте IVsMonitorSelection.GetCurrentSelection и IVSProject.GetMkDocument, чтобы получить имя файла элемента решения, на котором вы щелкнули:

    private void Execute(object sender, EventArgs e)
    {   
        IVsMultiItemSelect vsMIS = null;
        uint itemID = VSConstants.VSITEMID_NIL;
        IntPtr hierPtr = IntPtr.Zero;
        IntPtr selConPtr = IntPtr.Zero;
        IVsProject vsProject = null;

        ThreadHelper.ThrowIfNotOnUIThread();
        IVsMonitorSelection monitorSelection = Package.GetGlobalService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
        Assumes.Present(monitorSelection);

        try
        {
            ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(out hierPtr, out itemID, out vsMIS, out selConPtr));
            vsProject = Marshal.GetObjectForIUnknown(hierPtr) as IVsProject;
        }
        finally
        {
            if (hierPtr != IntPtr.Zero)
            {
                Marshal.Release(hierPtr);
            }
            if (selConPtr != IntPtr.Zero)
            {
                Marshal.Release(selConPtr);
            }
        }

        string documentMoniker;
        vsProject.GetMkDocument(itemID, out documentMoniker);

        string message = string.Format(CultureInfo.CurrentCulture, "filename of selected item: {0}", documentMoniker);
        string title = "Demo Package";
        VsShellUtilities.ShowMessageBox(this.package, message, title, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

}

Другие вопросы по теме