VSIX 获取与其上下文菜单关联的项目

VSIX Get Project associated with its Context Menu

我想为项目创建上下文菜单命令。通过将 .vsct 文件中的 id 设置为 "IDM_VS_CTXT_PROJNODE",我设法让命令显示在右侧菜单上。我的代码示例被正确调用:

    private FirstCommand(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 MenuCommand(StartNotepad, menuCommandID);
        commandService.AddCommand(menuItem);
    }


    private void StartNotepad(object sender, EventArgs e)
    {
        //example code  
        /*var process = new Process();
        process.StartInfo.FileName = "Notepad.exe";
        process.Start();*/
    }

我现在需要有关项目的信息(目录、名称等)。但是 vsix 项目上的所有示例仅显示如何获取当前项目(我什至不知道那是否是我单击的项目)或者对我不起作用。它们都是旧的,我不知道它们是否是当前的最佳实践。

所以我的问题是如何在 StartNotepad() 中获取有关该项目的信息? 感谢您的帮助。

使用以下方法获取您点击的项目:

private EnvDTE.UIHierarchyItem GetSelectedSolutionExplorerItem()
{
    EnvDTE.UIHierarchy solutionExplorer = dte.ToolWindows.SolutionExplorer;
    object[] items = solutionExplorer.SelectedItems as object[];
    if (items.Length != 1)
        return null;

    return items[0] as EnvDTE.UIHierarchyItem;
}

然后用GetSelectedSolutionExplorerItem()?.Object as EnvDTE.Project转换成项目。

Sergey 的回答帮助我找到了解决方案。唯一缺少的想法是如何以异步方式获取 dte:

private EnvDTE.UIHierarchyItem GetSelectedSolutionExplorerItem()
{
    ThreadHelper.ThrowIfNotOnUIThread();
    var dte = ServiceProvider.GetServiceAsync(typeof(DTE)).Result as DTE2;
    if (dte == null) return null;
    var solutionExplorer = dte.ToolWindows.SolutionExplorer;
    object[] items = solutionExplorer.SelectedItems as object[];
    if (items.Length != 1)
        return null;

    return items[0] as UIHierarchyItem;
}