using System.Collections.Generic; using System.Linq; using System.Reflection; // ReSharper disable once CheckNamespace namespace System.Runtime.Versioning { /// /// .NET目标框架的属性 /// https://docs.microsoft.com/zh-cn/dotnet/standard/frameworks /// struct TargetFramework { /// /// 当前主进程的 .NET目标框架 /// public static TargetFramework Current => new TargetFramework(Assembly.GetCallingAssembly()); /// /// 当前主进程 是否运行在 .NET Framework 上 /// public bool IsNETFramework => FrameworkName == Name.NETFramework; /// /// 当前主进程 是否运行在 .NET Core 上 /// public bool IsNETCore => FrameworkName == Name.NETCoreApp; /// /// 当前主进程 是否运行在 Xamarin.Android 上 /// public bool IsMonoAndroid => FrameworkName == Name.MonoAndroid; /// /// 当前主进程 是否运行在 Xamarin.iOS 上 /// public bool IsXamarin_iOS => FrameworkName == Name.Xamarin_iOS; /// /// 当前主进程 是否运行在 .NET for Windows Universal / .NETCore,Version=v5.0 / UWP 上 /// public bool IsUniversal => FrameworkName == Name.Universal; /// /// .NET目标框架名称 /// public Name FrameworkName { get; } /// /// .NET目标框架版本 /// public Version? Version { get; } /// /// public string? DisplayName { get; } /// /// .NET目标框架显示名称是否有值 /// public bool HasDisplayName => !string.IsNullOrWhiteSpace(DisplayName); /// /// .NET目标框架的版本属性构造函数 /// /// public TargetFramework(string frameworkName) : this(frameworkName, null) { } /// /// .NET目标框架的版本属性构造函数 /// /// public TargetFramework(Assembly assembly) : this(assembly.GetRequiredCustomAttribute()) { } /// /// .NET目标框架的版本属性构造函数 /// /// public TargetFramework(Type type) : this(type.Assembly) { } /// /// .NET目标框架的版本属性构造函数 /// /// public TargetFramework(TargetFrameworkAttribute attribute) : this(attribute.FrameworkName, attribute.FrameworkDisplayName) { } /// /// .NET目标框架的版本属性构造函数 /// /// /// public TargetFramework(string frameworkName, string? displayName) { const string vStartsWith = "Version=v"; Version? version = null; var array = Split(frameworkName); if (array?.Length >= 2) { FrameworkName = NameDictionary.FirstOrDefault(x => x.Value == array[0]).Key; if (FrameworkName == Name.Xamarin_iOS) version = SetVersionByFindSdkAssemblyVersionAttribute("Xamarin.iOS"); if (FrameworkName == Name.MonoAndroid) version = SetVersionByFindSdkAssemblyVersionAttribute("Mono.Android"); if (version == null) { var versionString = array[1]; if (versionString.StartsWith(vStartsWith)) { version = GetVersion(versionString[vStartsWith.Length..]); } } } else { FrameworkName = 0; } Version = version; DisplayName = displayName; } static string[]? Split(string? s, char separator = ',') => s?.Split(separator, StringSplitOptions.RemoveEmptyEntries); static Version? GetVersion(string? s) => Version.TryParse(s, out var v) ? v : null; static Version? SetVersionByFindSdkAssemblyVersionAttribute(string sdkAssemblyName) { var sdkAssembly = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == sdkAssemblyName); if (sdkAssembly == null) return default; var attr = sdkAssembly.GetCustomAttribute(); if (attr != null) return GetVersion(Split(attr.InformationalVersion)?.FirstOrDefault()); return default; } ///// ///// $"[assembly: TargetFramework(\"{Name.GetString()},Version=v{Version}\", FrameworkDisplayName = \"{DisplayName}\")]" ///// ///// //public string ToAssemblyAttributeString() => // $"[assembly: TargetFramework(\"{(NameDictionary.TryGetValue(FrameworkName, out var value) ? value : null)},Version=v{Version}\", FrameworkDisplayName = \"{DisplayName}\")]"; public override string ToString() { var name = FrameworkName switch { Name.NETFramework => ".NET Framework {0}", Name.NETCoreApp => ".NET Core {0}", Name.NETStandard => ".NET Standard {0}", Name.MonoAndroid => "Xamarin.Android {0}", Name.Xamarin_iOS => "Xamarin.iOS {0}", Name.Universal => "Windows Universal {0}", _ => "Unknown {0}", }; return string.Format(name, Version); } /// /// .NET目标框架名称 /// public enum Name : byte { /// /// .NET Framework / Mono /// NETFramework = 1, /// /// .NET Core /// NETCoreApp = 2, /// /// .NET Standard /// NETStandard = 3, /// /// Xamarin.Android /// https://developer.xamarin.com/releases/android /// MonoAndroid = 4, /// /// Xamarin.iOS /// https://developer.xamarin.com/releases/ios /// Xamarin_iOS = 5, /// /// .NET for Windows Universal / .NETCore,Version=v5.0 / UWP /// Universal = 6, } internal static readonly Dictionary NameDictionary = new Dictionary { { Name.Universal, ".NETCore" }, { Name.Xamarin_iOS, "Xamarin.iOS" }, { Name.MonoAndroid, "MonoAndroid" }, { Name.NETFramework, ".NETFramework" }, { Name.NETCoreApp, ".NETCoreApp" }, { Name.NETStandard, ".NETStandard" }, }; } }