.NET 4.7.2 项目为何生成带 net48 目录的 NuGet 包?
目标框架为 .NET Framework 4.7.2 的程序集,通常应放在 NuGet 包的 lib/net472/ 目录中。如果包内出现 net48,需要分别检查实际编译目标和打包时的目录映射。仅凭现有描述,还无法确定是哪项配置导致的。
TeamCity 构建代理上安装了 .NET Framework 4.8,并不足以证明项目会被改为面向 4.8,也不能据此解释包内目录名称。
1. 确认实际参与构建的项目和目标框架
先查 TeamCity 日志,确认参与构建的 .csproj、使用的配置,以及打包步骤所用的项目或 .nuspec 文件,避免检查的是本地项目,打包的却是另一个项目的输出。
对于 SDK 风格项目,目标框架通常这样设置:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
</Project>
如果使用 TargetFrameworks,检查是否包含 net48,以及是否确实需要为多个框架同时生成产物。
对于传统 .NET Framework 项目,对应属性通常是:
<PropertyGroup>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
</PropertyGroup>
这两种写法适用于不同的项目格式,请根据实际项目类型检查。还要查看带 Condition 的属性组,尤其是 TeamCity 使用的 Release 配置。
2. 检查打包方式是否指定了 net48
如果使用 .nuspec 打包,检查其中的 <files> 配置。文件的 target 可以直接决定包内目录,因此即使源 DLL 面向 4.7.2,也可能被放进 lib/net48。
例如,以下配置会将文件放入该目录:
<files>
<file src="bin\Release\MyLibrary.dll" target="lib\net48" />
</files>
确认 DLL 实际面向 .NET Framework 4.7.2 后,可以将映射改为:
<files>
<file src="bin\Release\MyLibrary.dll" target="lib\net472" />
</files>
示例中的 MyLibrary.dll 和源路径需要替换为实际值。如果还打包了其他程序集,也要逐一检查它们的来源和兼容性。
如果使用项目自身的 Pack 功能,检查是否有自定义 PackagePath、打包目标或脚本将文件固定写入 lib/net48。如果包内还有 ref/net48,也应检查对应的引用程序集配置。
3. 检查 TeamCity 传入的参数和共享配置
在 TeamCity 日志中查看实际执行的构建和打包命令,重点搜索:
TargetFramework
TargetFrameworks
TargetFrameworkVersion
net48
v4.8
例如,如果命令行传入了以下参数,需要核对它们是否覆盖了项目预期的目标框架:
/p:TargetFramework=net48
/p:TargetFrameworkVersion=v4.8
同时检查仓库中的 Directory.Build.props、Directory.Build.targets 和项目导入的其他配置文件。即使项目文件中写的是 4.7.2,所有属性求值完成后的值也可能不同。
需要进一步定位时,可以在实际使用的 MSBuild 命令上增加 /v:diag。例如,下面的命令可用于查看构建阶段的详细信息:
msbuild MyProject.csproj /t:Build /p:Configuration=Release /v:diag
示例中的配置和其他参数应与 TeamCity 保持一致。如果打包是独立步骤,还需要检查该步骤的日志。
4. 核对程序集和最终包是否来自同一次构建
检查被打包 DLL 的 TargetFrameworkAttribute。面向 .NET Framework 4.7.2 的程序集,其属性值通常应包含:
.NETFramework,Version=v4.7.2
如果程序集实际面向 4.8,应先修正构建目标并重新编译。仅将目录改为 net472,不会使面向 4.8 的程序集兼容 4.7.2。
如果程序集已面向 4.7.2,但包内仍是 lib/net48,应优先检查打包映射、自定义脚本,以及拿到的是否是旧包。清理相关构建输出和打包输出后重新生成,并核对 TeamCity 发布的 .nupkg 是否就是本次产物。
实际编译目标、打包目录和依赖分组需要保持一致。包内 .nuspec 的依赖分组也值得检查,但修改分组本身不会移动已放入 lib/net48 的文件。
备注:内容仅供参考。
