Visual Studio扩展:如何在选择时获取解决方案文件夹的“路径”?

DJon大师

上一个问题:Visual Studio扩展:如何禁用本机命令?

我构建了一个扩展来正确管理Git模块,为此,我在解决方案中有一个名为SubModules的文件夹。

我设法将上下文菜单添加到解决方案文件和项目文件中,但是在右键单击SubModules文件夹(即“删除”,“添加”)时,我想禁用一些本机命令。

我现在知道如何禁用所需的本机命令,但要这样做,我需要获取所选解决方案文件夹的“路径”。

我尝试实现IVsSelectionEvents,但是没有运气(o在转换之前不为null):

public int OnSelectionChanged(IVsHierarchy pHierOld, uint itemidOld, IVsMultiItemSelect pMISOld, ISelectionContainer pSCOld, IVsHierarchy pHierNew, uint itemidNew, IVsMultiItemSelect pMISNew, ISelectionContainer pSCNew)
{
    var o = GetProjectItem(pHierNew, itemidNew);
    return VSConstants.S_OK;
}

private static ProjectItem GetProjectItem(IVsHierarchy hierarchy, uint itemId)
{
    object o;
    if (hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out o) == VSConstants.S_OK)
    {
        var t = o as SolutionFolder; // ==> null

        return o as ProjectItem; // ==> null
    }
    return null;
}

使用我拥有的代码(从另一个问题开始)(我想在其中找到“路径”,但是我可以使用上面的“解决方案”进行管理),我尝试将其强制转换为SolutionFolder或FileProperties ...仍然没有运气; 即使MSDN告诉返回的对象应该是FileProperties类型。使用QuickWatch进行探索(Marshal.GetObjectForIUnknown(selectionContainerPtr) as ISelectionContainer),我可以进入私有属性_nodes,在那里,我可以看到我的SolutionFolder节点,并使用其Parent属性上移以确保它是我要阻止命令的文件夹。这是实际的代码:

private static void CommandEvents_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
    string name = GetCommandName(Guid, ID);

    if (name == "Project.AddNewSolutionFolder")
    {
        CancelDefault = true;
    }
    if (name == "Edit.Delete")
    {
        CancelDefault = true;

        IVsMultiItemSelect multiItemSelect = null;
        IntPtr hierarchyPtr = IntPtr.Zero;
        IntPtr selectionContainerPtr = IntPtr.Zero;
        uint itemid = 0;

        int hr = monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr);
        object[] selected = new object[2];
        (Marshal.GetObjectForIUnknown(selectionContainerPtr) as ISelectionContainer).GetObjects(2, 1, selected);


        var t = selected[0] as VSLangProj.FileProperties; // ==> null
        var t2 = selected[0] as SolutionFolder; // ==> null
        var b = 1;
    }

    if (name == "View.Branch")
    {
        //TODO: Could disable this command if not able to find the branch changing command (that would be cancelled and launch ours)
        menuBranchOpened = true;
    }

    if (menuBranchOpened)
    {
        var a = 1;
    }

}

我受到启发并尝试过(除了上面的那个似乎真的很接近之外,没有任何工作):

DJon大师

最后,浏览(更多)回答我上一个问题的其他人的网站,我终于找到了它。因此,我将分享一种我知道在解决方案资源管理器中选择了哪种类型的项目的方法。

applicationObject = await ServiceProvider.GetGlobalServiceAsync(typeof(SDTE)) as DTE2; // Was initiate in a method

private enum SelectionTypes
{
    Other = 0,
    InSubModules = 1,
    IsAFolder = 2,
    IsAProject = 4,
    InAProject = 8
}

private static List<SelectionTypes> GetSelectionTypes()
{
    ThreadHelper.ThrowIfNotOnUIThread();
    var selectionTypes = new List<SelectionTypes>();

    EnvDTE.UIHierarchy solutionExplorer = applicationObject.ToolWindows.SolutionExplorer;
    object[] items = solutionExplorer.SelectedItems as object[];
    //{ Name = "WindowBase" FullName = "Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase"}
    if (items.Length > 0)
    {
        for (int i = 0; i < items.Length; i++)
        {
            var selectionType = SelectionTypes.Other;
            var selectedItem = items[0] as EnvDTE.UIHierarchyItem;
            var currentItem = selectedItem;
            var subModulesParentsCount = 0;
            var countingSubModulesParents = false;
            var nbParents = -1;

            if (currentItem.Object.GetType().FullName == "Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject") selectionType |= SelectionTypes.IsAProject;
            if (currentItem.Object.GetType().FullName == "Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAFolderItem") selectionType |= SelectionTypes.IsAFolder;

            while (currentItem != null)
            {
                nbParents++;
                if (countingSubModulesParents) subModulesParentsCount++;

                if (currentItem.Name == "SubModules")
                {
                    subModulesParentsCount = 0;
                    countingSubModulesParents = true;
                }

                if (currentItem.Object.GetType().FullName == "Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProject") selectionType |= SelectionTypes.InAProject;

                currentItem = currentItem.Collection.Parent as EnvDTE.UIHierarchyItem;
            }

            if (selectionType == SelectionTypes.Other && nbParents != 0) selectionType |= SelectionTypes.IsAFolder;

            if (subModulesParentsCount == 1)
            {
                selectionType |= SelectionTypes.InSubModules;
            }

            selectionTypes.Add(selectionType);
        }
    }

    return selectionTypes;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Visual Studio扩展中,如何响应“打开文件夹”以及“打开解决方案”?

如何为Visual Studio中的解决方案动态创建解决方案文件夹?

Visual Studio 2017:如何在解决方案文件夹中包含NuGet包

如何在Visual Studio 2019的Github解决方案中将不同文件夹中的项目推送或上载?

如何在Visual Studio 2013解决方案资源管理器中获取文件路径?

Visual Studio扩展:在解决方案资源管理器中获取当前所选文件的路径

如何在Visual Studio 2019中的解决方案资源管理器中打开包含文件的文件夹

如何将 Unreal Visual Studio 解决方案文件生成到特定文件夹中

在Visual Studio 2013的解决方案文件夹中搜索代码中的特定模式

Visual Studio解决方案中使用的.vs文件夹是什么?

无法识别解决方案文件夹中的Visual Studio 2017 Nuget.config

Visual Studio将项目文件夹复制到输出目录(WPF解决方案)

Visual Studio:解决方案文件夹的自动(重新)生成

如何在 Visual Studio 中为不属于解决方案的 Python 文件管理 Python 搜索路径或引用?

Visual Studio解决方案资源管理器不显示文件和文件夹

如何在Linux下构建Visual Studio解决方案?

如何在 Visual Studio 2017 中保存解决方案

在Visual Studio外部更改文件时,如何更新TFS中的解决方案文件?

使用CMake在同一文件夹中生成两个Visual Studio解决方案

通过提供Visual Studio解决方案的发布文件夹来部署WPF应用程序

无法访问Visual Studio 2010解决方案资源管理器中的文件夹

如何在解决方案加载时禁用Visual Studio 2015及更高版本的自动Bower安装?

如何在Visual Studio解决方案中将特定文件添加到.gitignore?

如何在Visual Studio 2013解决方案中删除最近打开的文件

如何在 Visual Studio 解决方案中拥有“可选”文件?

如何在Visual Studio 2013解决方案中删除最近打开的文件

如何在Visual Studio解决方案中取消删除文件

如何在Visual Studio 2019中更新.sln(解决方案)文件

如何在Visual Studio的解决方案资源管理器中添加文件?