Я создал специальную команду для проекта 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
, который представляет саму среду разработки.
Взгляните на этот пример:
Чтобы поддерживать параметры при вызове вашей команды (например, вызове команды 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);
}
Искренне,
Спасибо за предложение, как установить путь к файлу для аргументов команды, я думаю, что описание параметра похоже на «ключ». Когда я щелкаю правой кнопкой мыши по узлу проекта, как мне установить путь к папке проекта для аргументов?
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);
}
Если вы посмотрите на справочный документ EventArgs, вы увидите, что в нем нет необходимой вам информации, DTE должен быть правильным способом, взгляните на мой ответ. :)