能否通过编程方式获取.NET Core解决方案的NuGet包版本?
获取项目引用特定NuGet包版本的实现方案
你之前使用的Assembly.GetAssembly(typeof(XXX)).GetName().Version.ToString()方法获取的是程序集版本,属于程序集自身的元数据属性,和NuGet包版本是两套独立的版本体系。不少NuGet包作者在迭代时不会同步更新程序集版本(比如仅发布补丁版本时保持程序集版本不变,减少不必要的绑定重定向),因此两者不一致是正常现象,无法通过程序集版本反推NuGet包版本。
方案1:运行时解析deps.json(推荐,适配绝大多数.NET Core/.NET 5+场景)
SDK风格的.NET项目编译后会在输出目录生成与入口程序集同名的.deps.json文件,该文件会完整记录所有实际引用的NuGet包ID、精确版本,和项目实际引用的包版本完全一致,不受程序集版本差异影响。
- 首先在项目中安装
Microsoft.Extensions.DependencyModel包,用于便捷解析deps.json内容 - 参考以下代码读取目标包版本:
using Microsoft.Extensions.DependencyModel; using System.Linq; using System.Reflection; // 替换为你要查询的NuGet包ID,匹配时默认不区分大小写 const string TargetPackageId = "你要查询的NuGet包ID"; // 入口项目直接取Default即可;如果在类库中使用,传入类库内任意类型的程序集 var depsCtx = DependencyContext.Default; // var depsCtx = DependencyContext.Load(Assembly.GetAssembly(typeof(类库中的任意类型))); var matchedPackage = depsCtx.RuntimeLibraries .FirstOrDefault(lib => lib.Type == "package" && lib.Name.Equals(TargetPackageId, StringComparison.OrdinalIgnoreCase)); if (matchedPackage != null) { // 输出结果即为目标NuGet包的精确版本 string nugetPackageVersion = matchedPackage.Version.ToString(); }
方案2:编译时嵌入版本信息(无额外依赖,性能最高)
如果只需要固定获取某几个特定NuGet包的版本,可以通过MSBuild目标在编译阶段直接将包版本写入程序集元数据,运行时直接读取即可,不需要解析额外文件,也不受运行时绑定重定向影响。
- 编辑你的项目文件(.csproj),在文件内添加如下MSBuild配置,将配置中的包ID替换为你需要查询的目标包即可:
<Target Name="EmbedNugetVersionToAssembly" BeforeTargets="CoreCompile"> <ItemGroup> <AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute"> <_Parameter1>Custom_NugetVersion_TargetPackage</_Parameter1> <_Parameter2>%(PackageReference.Version)</_Parameter2> <!-- 这里的判断条件替换为你要查询的NuGet包ID --> <Condition>%(PackageReference.Identity) == '目标NuGet包ID'</Condition> </AssemblyAttribute> </ItemGroup> </Target>
- 运行时通过读取程序集特性直接获取版本:
using System.Linq; using System.Reflection; var assembly = Assembly.GetEntryAssembly(); // 类库场景替换为对应类库的程序集 var versionMeta = assembly.GetCustomAttributes<AssemblyMetadataAttribute>() .FirstOrDefault(attr => attr.Key == "Custom_NugetVersion_TargetPackage"); if (versionMeta != null) { string nugetPackageVersion = versionMeta.Value; }
方案3:.NET Framework 非SDK风格项目适配
如果你的项目是基于传统.NET Framework、使用packages.config管理NuGet包,优先使用方案2的MSBuild嵌入方式,不需要调整现有包管理逻辑,兼容性最好。
注意:不要尝试通过解析packages.config、项目源码文件的方式在运行时获取版本,这类文件在发布后大概率不会被复制到输出目录,且记录的版本可能和实际编译时使用的版本存在偏差,结果不可靠。
内容的提问来源于stack exchange,提问作者Pavel_K
相关产品推荐
相关产品推荐

