如何在.NET应用中正确获取非特定版本的运行时标识符(RID)
我明白你想要的是那种不带版本后缀的通用RID——比如把win10-x64转换成win-x64,而且你也注意到了.NET官方文档明确警告不要手动解析或构造RID,这点非常关键,因为RID的格式属于实现细节,硬写解析逻辑很容易在未来版本中出问题。下面给你两个符合官方规范的解决方案:
方案1:构建/发布阶段用MSBuild内置属性(推荐)
如果你的需求是在构建或者发布流程中获取这个通用RID,其实.NET SDK已经帮你准备好了现成的MSBuild属性:RuntimeIdentifierWithoutVersion。它会自动把带版本的RID转换成无版本的形式,比如ubuntu22.04-x64会变成ubuntu-x64,完全不需要自己动手解析。
在项目文件中直接使用
你可以在.csproj或.vbproj里直接引用这个属性,比如添加一段输出日志:
<PropertyGroup> <!-- 把无版本RID打印到构建控制台 --> <Message Text="通用RID: $(RuntimeIdentifierWithoutVersion)" Importance="High" /> </PropertyGroup>
如果发布时通过命令行指定了-r参数(比如dotnet publish -r win10-x64),这个属性会自动对应到win-x64,完全不需要额外处理。
注入到代码中使用
如果需要在运行时代码里用到这个值,可以通过MSBuild把它注入到项目的常量里。比如在项目文件中添加以下配置:
<PropertyGroup> <VersionAgnosticRID>$(RuntimeIdentifierWithoutVersion)</VersionAgnosticRID> </PropertyGroup> <Target Name="InjectVersionAgnosticRID" BeforeTargets="CoreCompile"> <WriteLinesToFile File="Properties\VersionAgnosticRID.cs" Lines="namespace YourAppNamespace; public static class RuntimeInfo { public const string VersionAgnosticRID = "$(VersionAgnosticRID)"; }" Overwrite="true" Encoding="UTF-8" /> </Target> <ItemGroup> <Compile Include="Properties\VersionAgnosticRID.cs" /> </ItemGroup>
这样在代码里就可以直接通过RuntimeInfo.VersionAgnosticRID拿到通用RID了,全程用官方提供的机制,没有任何解析风险。
方案2:运行时通过安全API推导
如果必须在运行时动态获取(而非构建阶段),那我们可以用官方提供的稳定API来推导,完全避开解析RID的操作:
using System.Runtime.InteropServices; public static class RuntimeHelper { public static string GetVersionAgnosticRID() { // 确定操作系统前缀 string osPrefix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win" : RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "linux" : RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "osx" : // 其他平台默认返回原始RID,或者根据需要扩展 RuntimeInformation.RuntimeIdentifier; // 确定架构后缀 string archSuffix = RuntimeInformation.ProcessArchitecture switch { Architecture.X64 => "-x64", Architecture.X86 => "-x86", Architecture.Arm => "-arm", Architecture.Arm64 => "-arm64", _ => string.Empty }; return $"{osPrefix}{archSuffix}"; } }
这个方法依赖IsOSPlatform和ProcessArchitecture这两个官方保证稳定的API,完全符合文档要求,不会因为RID格式的变更而失效。如果需要支持更多小众平台,只需要在分支里添加对应的前缀即可。
为什么官方不建议解析RID?
官方文档之所以警告不要手动解析RID,是因为RID的格式是实现细节,并非公开的稳定契约。比如Windows的RID从早期的win8-x64演变到win10-x64、win11-x64,未来可能还会有新的命名格式;Linux发行版的RID更是多样(比如ubuntu20.04-x64、fedora38-x64),硬写正则替换版本号很容易漏掉边缘情况,导致代码在新环境下失效。
内容的提问来源于stack exchange,提问作者radoslawik

