我如何识别 ASP.NET 扩展中的 ASP.NET 核心项目

How can I recognize an ASP.NET Core project in a Visual Studio extension

在我的 Visual Studio 包中,我查看解决方案中的每个项目,我需要确定它是什么类型的项目。

过去,我使用类似于 Carlos Quintero here 描述的技术来获取项目 GUID 并在列表中查找特定的 GUID。

对于ASP.NET核心项目,我找过

AspNetCore:  "{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}"
AspNetCore2: "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"

如果项目使用旧式项目文件,这可能仍然有效。

但是,如果使用新的Visual Studio项目系统,它就不起作用了。

这是我目前使用的项目文件:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" />
  </ItemGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
  </ItemGroup>

  <ItemGroup>
    <Compile Update="App_GlobalResources\Resources.Designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Update="App_GlobalResources\Resources.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Controllers\App_LocalResources\HomeController.resx.en.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Controllers\HomeController.en.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Controllers\HomeController.nl.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Controllers\HomeController.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Controllers\StudentController.en.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Models\Student.en.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Views\Home\About.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Views\Home\Contact.en.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Views\Home\Index.en.resx">
      <Generator></Generator>
    </EmbeddedResource>
    <EmbeddedResource Update="Resources\Views\Home\Index.resx">
      <Generator></Generator>
    </EmbeddedResource>
  </ItemGroup>

</Project>

如您所见,它不包含项目 GUID。

使用How to detect whether a project is a CPS project中描述的技术,我可以检测到它是一个 CPS(通用项目系统)项目。

使用Finding CPS in a VS project中描述的技术,我可以得到"unconfigured project",我也可以得到"configured project"(虽然我不确定我是否理解"unconfigured" 和 "configured" 在这种情况下是什么意思)。

此时我卡住了。我不知道如何确定它是否是 ASP.NET 核心项目。

最好的办法可能是获取 TargetFramework 属性,即 netcoreapp2.0。有什么方法可以从 CPS 项目对象中获取 TargetFramework 属性?

还是我的处理方式完全错误?

您可以寻找 TargetFrameworkMoniker:

    public static bool IsNetCore2(this Project project)
    {
        return project.Properties.Item("TargetFrameworkMoniker").Value.ToString().Contains(".NETCoreApp,Version=v2.");
    }

https://github.com/ErikEJ/EFCorePowerTools/blob/master/src/GUI/EFCorePowerTools/Extensions/ProjectExtensions.cs#L75

要检测 ASP.NET 核心,我认为您必须解析 csproj 文件: 并寻找 Sdk="Microsoft.NET.Sdk.Web"

可能一个好的解决方案是在 nuget 包 Microsoft.Build.

中使用 MsBuild API

如果您有 ENVDte.Project 对象,您可以使用全名 属性 获取项目文件的路径。

然后就可以访问Sdk 属性如下:

void foo ( ENVDte.Project prj )
{
  var MsBuildProject = new Microsoft.Build.Evaluation.Project ( prj.FullName ) ;
  
  if ( string.IsNullOrEmpty ( MsBuildProject.Xml.Sdk ) )
  {
    // Not .NET core
  }
  else if ( MsBuildProject.Xml.Sdk == "Microsoft.NET.Sdk.Web" )
  {
    // ASP.NET core
  }
  else if ( MsBuildProject.Xml.Sdk == "Microsoft.NET.Sdk.WindowsDesktop" )
  {
    // .NET core desktop app
  }
}  

这实际上与解析项目文件并查找 Sdk="Microsoft.NET.Sdk.Web" 相同,正如 Eric 已经建议的那样,但我更喜欢尽可能使用 API。

如果您要查找有关该项目的其他详细信息,MsBuild 项目对象中有更多信息,例如集合 AllEvaluatedItems 或集合 AllEvaluatedProperties。