.NET Core/.NET Standard 2.0如何检测Android/iOS等移动操作系统
结论
可以实现Android、iOS、iPadOS等移动操作系统的检测,但.NET Standard 2.0、.NET Core 3.1及更早版本的基础库没有内置相关API——大家常用的RuntimeInformation.IsOSPlatform()方法原生只支持识别Windows、macOS、Linux三类桌面/服务器系统,需要结合项目编译配置或运行时特征实现移动平台检测,两种常用方案如下:
方案1:多目标编译+编译常量判断(最稳定,优先选)
如果你的项目支持多目标编译,直接给类库/应用加上移动端对应的目标框架,利用官方SDK内置的编译常量做判断,零额外依赖,不会出现误判。
首先在项目文件中配置多目标框架:
<TargetFrameworks>netstandard2.0;MonoAndroid12.0;Xamarin.iOS1.0</TargetFrameworks>
对应的检测代码:
using System.Runtime.InteropServices; // 仅在iOS编译目标下引用该命名空间 #if __IOS__ using UIKit; #endif public static class PlatformDetector { public static bool IsAndroid() { #if __ANDROID__ return true; #else return false; #endif } public static bool IsIOS() { #if __IOS__ return true; #else return false; #endif } public static bool IsIPadOS() { #if __IOS__ // iPadOS与iOS共用运行时标记,需结合设备类型判断 return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad; #else return false; #endif } public static bool IsDesktopPlatform() { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux); } }
编译期判断的逻辑只会被打包进对应平台的产物中,不会在其他平台运行时出现误判。
方案2:单netstandard2.0目标的运行时检测
如果项目只能输出netstandard2.0单版本、无法引入移动端SDK做编译期判断,可以用反射+系统特征做运行时检测,不需要额外安装NuGet包:
using System; using System.Reflection; public static class PlatformDetector { public static bool IsAndroid() { if (Environment.OSVersion.Platform != PlatformID.Unix) return false; try { // 反射检测Android运行时专属类型 var androidBuildType = Type.GetType("Android.OS.Build, Mono.Android", false); return androidBuildType != null; } catch { return false; } } public static bool IsIOSOrIPadOS(out bool isIPadOS) { isIPadOS = false; if (Environment.OSVersion.Platform != PlatformID.MacOSX) return false; try { // 反射检测iOS运行时专属基础类型 var nsObjectType = Type.GetType("Foundation.NSObject, Xamarin.iOS", false); if (nsObjectType == null) return false; // 反射判断设备类型区分iPhone和iPad var deviceType = Type.GetType("UIKit.UIDevice, Xamarin.iOS", false); if (deviceType == null) return true; var currentDeviceProp = deviceType.GetProperty("CurrentDevice", BindingFlags.Public | BindingFlags.Static); var currentDevice = currentDeviceProp?.GetValue(null); var idiomProp = deviceType.GetProperty("UserInterfaceIdiom", BindingFlags.Public | BindingFlags.Instance); var idiomValue = Convert.ToInt32(idiomProp?.GetValue(currentDevice)); // 枚举值:0=Phone,1=Pad isIPadOS = idiomValue == 1; return true; } catch { return false; } } }
注意事项
- 不要靠UserAgent、系统文件路径这类弱特征判断系统,很容易受沙盒权限、系统版本更新影响,准确率极低
- 如果项目升级到.NET 5及以上版本,基础库已经原生支持移动平台检测,直接调用
RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID"))、RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS"))即可,不需要自行实现逻辑 - iPadOS目前没有独立的平台标记,不管是旧版Xamarin还是新版.NET,都会将其识别为iOS平台,必须额外判断设备类型才能区分
内容的提问来源于stack exchange,提问作者Ejrr1085
相关产品推荐
相关产品推荐

