MSBuild 遇上 .NET Core 的 csproj 文件

本文详解 .NET Core 的 csproj 文件

在上一篇 MSBuild 入门 说到,
如果通过 Visual Studio 2019 创建一个 Web项目 的时候,csproj 文件是这样子的:

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>

.NET Core 的 csproj 文件变得如此不同的原因是:

因为隐式和默认值的原因,所以更改极大地简化了项目文件,
但官方提供了如何像 MSBuild 一样查看整个项目

可以在命令行 CD 切换到的项目路径,也就是说该路径下有一个 .csproj 的文件,
然后以下执行命令:

1
dotnet msbuild -pp:fullproject.xml

则会在该目录下生成一个 fullproject.xml 文件,内容是把 .csproj 所以隐式和默认的内容完整的显示出来。

Sdk="Microsoft.NET.Sdk.Web",会隐式引用包 Microsoft.NETCore.AppMicrosoft.AspNetCore.App

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>

相当于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<!-- 会隐式引用,这里只是演示,不建议显示手动添加 -->
<PackageReference Include="Microsoft.NETCore.App">
</ItemGroup>
<ItemGroup>
<!-- 会隐式引用,这里只是演示,不建议显示手动添加 -->
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>

如果将 Sdk="Microsoft.NET.Sdk.Web" 修改成 Sdk="Microsoft.NET.Sdk"
那么则不会隐式引用 Microsoft.AspNetCore.App~

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>

相当于:

1
2
3
4
5
6
7
8
9
10
11
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<!-- 会隐式引用,这里只是演示,不建议显示手动添加 -->
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>

如果将:

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>

修改成:

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>

那么在 Visual Studio 的 解决方案资源管理器
项目的 依赖项框架中的 Microsoft.AspNetCore.App 则会消失~

Sdk 属性的值有:

  • Microsoft.NET.Sdk 的 .NET Core SDK
  • Microsoft.NET.Sdk.Web 的 .NET Core Web SDK
  • Microsoft.NET.Sdk.Razor 的 .NET Core Razor 类库 SDK
  • Microsoft.NET.Sdk.Worker 的 .NET Core Worker Service(自 .NET Core 3.0 起)
  • Microsoft.NET.Sdk.WindowsDesktop 的 .NET Core WinForms 和 WPF(自 .NET Core 3.0 起)

<TargetFramework> 元素标记的作用是可以指定项目面向的 .NET 版本。
框架定位有助于确保应用程序仅使用指定框架版本中可用的功能。
其元素标记值可以有是:

目标框架名字对象 (TFM) 目标 Framework 最新稳定版本
netstandard2.1 .NET Standard 2.1
netcoreapp3.1 .NET Core 3.1
net48 .NET Framework 4.8

所有的值可以查看SDK 样式项目中的目标框架
想在 VS 中操作,可以查看 框架定位概述

在指定多个目标框架时,可有条件地为每个目标框架引用程序集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
</PropertyGroup>

<!-- Conditionally obtain references for the .NET Framework 4.0 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
<Reference Include="System.Net" />
</ItemGroup>

<!-- Conditionally obtain references for the .NET Framework 4.5 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>

</Project>

对应的可以在库或应用中,编写条件代码以为每个目标框架编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyClass
{
static void Main()
{
#if NET40
Console.WriteLine("Target framework: .NET Framework 4.0");
#elif NET45
Console.WriteLine("Target framework: .NET Framework 4.5");
#else
Console.WriteLine("Target framework: .NET Standard 1.4");
#endif
}
}

参考资料

MSBuild 如何生成项目
.NET Core 的 csproj 格式的新增内容
如何:使用 MSBuild 项目 SDK

觉得文章对您有帮助,请我喝瓶肥宅快乐水可好 (๑•̀ㅂ•́)و✧
  • 本文作者: 阿彬~
  • 本文链接: https://iweixubin.github.io/posts/msbuild/dotnet-core-csproj/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 免责声明:本媒体部分图片,版权归原作者所有。因条件限制,无法找到来源和作者未进行标注。
         如果侵犯到您的权益,请与我联系删除