|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System;
public static partial class PlatformDetection
{
//
// Do not use the " { get; } = <expression> " pattern here. Having all the initialization happen in the type initializer
// means that one exception anywhere means all tests using PlatformDetection fail. If you feel a value is worth latching,
// do it in a way that failures don't cascade.
//
public static bool HasWindowsShell => IsWindows && IsNotWindowsServerCore && IsNotWindowsNanoServer && IsNotWindowsIoTCore;
public static bool IsUap => IsInAppContainer || IsNetNative;
public static bool IsNetNative => RuntimeInformation.FrameworkDescription.StartsWith(".NET Native", StringComparison.OrdinalIgnoreCase);
public static bool IsNetCore => RuntimeInformation.FrameworkDescription.StartsWith(".NET Core", StringComparison.OrdinalIgnoreCase);
public static bool IsNotWindows8x => !IsWindows8x;
public static bool IsNotWindowsNanoServer => !IsWindowsNanoServer;
public static bool IsNotWindowsServerCore => !IsWindowsServerCore;
public static bool IsNotWindowsIoTCore => !IsWindowsIoTCore;
public static bool IsNotWindowsHomeEdition => !IsWindowsHomeEdition;
public static bool IsArmProcess => RuntimeInformation.ProcessArchitecture == Architecture.Arm;
public static bool IsNotArmProcess => !IsArmProcess;
public static bool IsArm64Process => RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
public static bool IsNotArm64Process => !IsArm64Process;
public static bool IsArmOrArm64Process => IsArmProcess || IsArm64Process;
public static bool Is32BitProcess => IntPtr.Size == 4;
public static bool IsMonoRuntime => Type.GetType("Mono.RuntimeStructs") is object;
public static bool IsNotMonoRuntime => !IsMonoRuntime;
public static bool IsMonoInterpreter => GetIsRunningOnMonoInterpreter();
public static bool IsNativeAot => IsNotMonoRuntime && !IsReflectionEmitSupported;
// Changed to `true` when trimming
public static bool IsBuiltWithAggressiveTrimming => IsNativeAot;
public static bool IsNotBuiltWithAggressiveTrimming => !IsBuiltWithAggressiveTrimming;
public static bool IsNotInAppContainer => !IsInAppContainer;
public static bool IsWinRTSupported => IsWindows && !IsWindows7;
public static bool IsNotWinRTSupported => !IsWinRTSupported;
public static bool IsNotMacOsHighSierraOrHigher => !IsMacOsHighSierraOrHigher;
public static bool IsDomainJoinedMachine => !Environment.MachineName.Equals(Environment.UserDomainName, StringComparison.OrdinalIgnoreCase);
public static bool IsNotNetNative => !IsNetNative;
// Windows - Schannel supports alpn from win8.1/2012 R2 and higher.
// Linux - OpenSsl supports alpn from openssl 1.0.2 and higher.
// OSX - SecureTransport doesn't expose alpn APIs. #30492
public static bool SupportsAlpn => (IsWindows && !IsWindows7) ||
(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) &&
(OpenSslVersion.Major >= 1 && (OpenSslVersion.Minor >= 1 || OpenSslVersion.Build >= 2)));
public static bool SupportsClientAlpn => SupportsAlpn ||
(RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && OSXVersion > new Version(10, 12));
// Officially, .Net Native only supports processes running in an AppContainer. However, the majority of tests still work fine
// in a normal Win32 process and we often do so as running in an AppContainer imposes a substantial tax in debuggability
// and investigatability. This predicate is used in ConditionalFacts to disable the specific tests that really need to be
// running in AppContainer when running on .NetNative.
public static bool IsNotNetNativeRunningAsConsoleApp => !(IsNetNative && !IsInAppContainer);
private static readonly Lazy<bool> s_isWindowsSubsystemForLinux = new(GetIsWindowsSubsystemForLinux);
public static bool IsWindowsSubsystemForLinux => s_isWindowsSubsystemForLinux.Value;
public static bool IsNotWindowsSubsystemForLinux => !IsWindowsSubsystemForLinux;
private static bool GetIsWindowsSubsystemForLinux()
{
// https://github.com/Microsoft/BashOnWindows/issues/423#issuecomment-221627364
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
const string versionFile = "/proc/version";
if (File.Exists(versionFile))
{
string s = File.ReadAllText(versionFile);
if (s.Contains("Microsoft") || s.Contains("WSL"))
{
return true;
}
}
}
return false;
}
private static readonly Lazy<bool> s_largeArrayIsNotSupported = new(IsLargeArrayNotSupported);
[MethodImpl(MethodImplOptions.NoOptimization)]
private static bool IsLargeArrayNotSupported()
{
try
{
byte[] tmp = new byte[int.MaxValue];
return tmp is null;
}
catch (OutOfMemoryException)
{
return true;
}
}
public static bool IsNotIntMaxValueArrayIndexSupported => s_largeArrayIsNotSupported.Value;
public static bool IsNonZeroLowerBoundArraySupported
{
get
{
if (s_lazyNonZeroLowerBoundArraySupported is null)
{
bool nonZeroLowerBoundArraysSupported = false;
try
{
Array.CreateInstance(typeof(int), [5], [5]);
nonZeroLowerBoundArraysSupported = true;
}
catch (PlatformNotSupportedException)
{
}
s_lazyNonZeroLowerBoundArraySupported = Tuple.Create<bool>(nonZeroLowerBoundArraysSupported);
}
return s_lazyNonZeroLowerBoundArraySupported.Item1;
}
}
private static volatile Tuple<bool> s_lazyNonZeroLowerBoundArraySupported;
// Tracked in: https://github.com/dotnet/corert/issues/3643 in case we change our mind about this.
public static bool IsInvokingStaticConstructorsSupported => !IsNetNative;
// System.Security.Cryptography.Xml.XmlDsigXsltTransform.GetOutput() relies on XslCompiledTransform which relies
// heavily on Reflection.Emit
public static bool IsXmlDsigXsltTransformSupported => !IsUap;
private static bool GetIsRunningOnMonoInterpreter()
{
#if NETCOREAPP
return IsMonoRuntime && RuntimeFeature.IsDynamicCodeSupported && !RuntimeFeature.IsDynamicCodeCompiled;
#else
return false;
#endif
}
#if NETCOREAPP
public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported;
public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported;
#else
public static bool IsReflectionEmitSupported => true;
#endif
}
|