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" },
};
}
}