Community.VisualStudio.Toolkit icon indicating copy to clipboard operation
Community.VisualStudio.Toolkit copied to clipboard

[BUG] IsKindAsync not working [for me?]

Open ErikEJ opened this issue 4 years ago • 14 comments

IsKindAsync does not return true, and my project menu item remains hidden. What am I doing wrong?

(Project is a .NET Core 3.1 Console app, C#, .csproj)

    private async void OnProjectMenuBeforeQueryStatus(object sender, EventArgs e)
    {
        var menuCommand = sender as MenuCommand;

        if (menuCommand == null)
        {
            return;
        }

        var project = await VS.Solutions.GetActiveProjectAsync();

        if (project == null)
        {
            return;
        }

        menuCommand.Visible =
            project.FullPath.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase);
            //TODO Report bug
            //(await project.IsKindAsync(ProjectTypes.CSHARP)) ||
            //(await project.IsKindAsync(ProjectTypes.DOTNET_CORE));

        return;
    }

ErikEJ avatar Aug 31 '21 05:08 ErikEJ

Related issue https://github.com/ErikEJ/EFCorePowerTools/issues/1046

ErikEJ avatar Aug 31 '21 05:08 ErikEJ

Interesting. Looks like SDK-style projects are not IVsAggregatableProject.

This line is false for SDK-style projects, but true for other projects. https://github.com/VsixCommunity/Community.VisualStudio.Toolkit/blob/5c266503acbf4fc532a3d4b5b167745d33d3891e/src/Community.VisualStudio.Toolkit.Shared/ExtensionMethods/IVsHierarchyExtensions.cs#L85

reduckted avatar Sep 04 '21 12:09 reduckted

@reduckted any idea on how to fix?

madskristensen avatar Nov 02 '21 21:11 madskristensen

Unfortunately, no. I had a search across GitHub for places that were using IVsAggregatableProject and I didn't see anywhere that was using an alternative technique when the hierarchy doesn't implement that interface.

reduckted avatar Nov 03 '21 11:11 reduckted

🤔 I'm just thinking out loud here. I wonder if using project capabilities are a better choice in this situation. For a .NET Framework C# project, the capabilities are:

AppServicePublish
CSharp
FolderPublish
Managed
Publish
SharedProjectReferences
WindowsForms

And for a .NET Core C# application they are:

.NET
AllTargetOutputGroups
AppDesigner
AssemblyReferences
CPS
CSharp
ClassDesigner
...plus another 36 capabilities...
VisualStudioWellKnownOutputGroups
WinRTReferences

From that, you could detect a .NET Core C# project by looking for the CSharp and CPS capabilities. A .NET Framework C# project would have the CSharp capability but not the CPS capability.

I wonder if each project type listed in ProjectTypes.cs has a corresponding capability...

reduckted avatar Nov 04 '21 10:11 reduckted

That would work fine, can I do This today With the toolkit?

ErikEJ avatar Nov 04 '21 10:11 ErikEJ

Not directly with the toolkit, but it's not a lot of code:

Project project = await VS.Solutions.GetActiveProjectAsync();
project.GetItemInfo(out IVsHierarchy hierarchy, out _, out _);

bool isCSharp = hierarchy.IsCapabilityMatch("CSharp");

bool isCSharpAndNetCore = hierarchy.IsCapabilityMatch("CSharp & CPS");

bool isCSharpAndNetFx = hierarchy.IsCapabilityMatch("CSharp & !CPS");

Here's some more information about the capability expressions: IsCapabilityMatch(IVsHierarchy, String)

This is what I used to get all of the capabilities:

HierarchyUtilities.TryGetHierarchyProperty<string>(h, itemId, (int)__VSHPROPID5.VSHPROPID_ProjectCapabilities, out string value);
string[] capabilities = (value ?? "").Split(' ');

reduckted avatar Nov 04 '21 11:11 reduckted

Cool, thanks!

ErikEJ avatar Nov 04 '21 11:11 ErikEJ

Same question for ASP.Net core project types. is there any capability or something which gives info about which sdk is in use? I found a workaround here. it uses Microsoft.Build to analyse sdk types. this is working fine but not sure if it's a good idea to have dependencies to Microsoft.Build...

jaybee82 avatar Nov 30 '21 09:11 jaybee82

@jaybee82 you should be able to look at the capabilities as mentioned above.

That us what works fine for me, and I would imagine there is a Web related capability also.

ErikEJ avatar Nov 30 '21 11:11 ErikEJ

Ok, thank you. i will check. for some reason i missed comment from @reduckted how to list all capabilities.

jaybee82 avatar Nov 30 '21 12:11 jaybee82

The CI build has a way to ask for Project.IsCapabilityMatch(string). It would be cool if we can make a list of known capability names so we can provide IntelliSense for it. Perhaps an overload that takes an enum

madskristensen avatar Nov 30 '21 19:11 madskristensen

Here's a list of some of the known capabilities: https://github.com/microsoft/VSProjectSystem/blob/master/doc/overview/project_capabilities.md

It's not a complete list though, because it's missing these ASP.NET Core capabilities: https://github.com/dotnet/sdk/blob/a30e465a2e2ea4e2550f319a2dc088daaafe5649/src/WebSdk/ProjectSystem/Targets/Microsoft.NET.Sdk.Web.ProjectSystem.targets#L28-L31

reduckted avatar Nov 30 '21 21:11 reduckted