示例#1
0
    /// <summary>
    ///     Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes.
    /// </summary>
    public static void SetPlatform()
    {
        var current = Platform.Unknown;

        // For old Mono, get from a private property to accurately get the platform.
        // static extern PlatformID Platform
        var    p_Platform = typeof(Environment).GetProperty("Platform", BindingFlags.NonPublic | BindingFlags.Static);
        string platID;

        if (p_Platform != null)
        {
            platID = p_Platform.GetValue(null, new object[0]).ToString();
        }
        else
        {
            // For .NET and newer Mono, use the usual value.
            platID = Environment.OSVersion.Platform.ToString();
        }
        platID = platID.ToLowerInvariant();

        if (platID.Contains("win"))
        {
            current = Platform.Windows;
        }
        else if (platID.Contains("mac") || platID.Contains("osx"))
        {
            current = Platform.MacOS;
        }
        else if (platID.Contains("lin") || platID.Contains("unix"))
        {
            current = Platform.Linux;
        }

        if (current.Is(Platform.Linux) && Directory.Exists("/data") && File.Exists("/system/build.prop"))
        {
            current = Platform.Android;
        }
        else if (current.Is(Platform.Unix) && Directory.Exists("/System/Library/AccessibilityBundles"))
        {
            current = Platform.iOS;
        }

        if (current.Is(Platform.Windows))
        {
            var windowsVersionInfo = new WindowsOSVersionInfoExW();
            RtlGetVersion(ref windowsVersionInfo);

            WindowsVersion = new Version((int)windowsVersionInfo.dwMajorVersion,
                                         (int)windowsVersionInfo.dwMinorVersion, 0,
                                         (int)windowsVersionInfo.dwBuildNumber);
        }

        // Is64BitOperatingSystem has been added in .NET Framework 4.0
        var m_get_Is64BitOperatingSystem =
            typeof(Environment).GetProperty("Is64BitOperatingSystem")?.GetGetMethod();

        if (m_get_Is64BitOperatingSystem != null)
        {
            current |= (bool)m_get_Is64BitOperatingSystem.Invoke(null, new object[0]) ? Platform.Bits64 : 0;
        }
        else
        {
            current |= IntPtr.Size >= 8 ? Platform.Bits64 : 0;
        }

        if ((current.Is(Platform.MacOS) || current.Is(Platform.Linux)) && Type.GetType("Mono.Runtime") != null)
        {
            string arch;
            IntPtr result;

            if (current.Is(Platform.MacOS))
            {
                var utsname_osx = new utsname_osx();
                result = uname_osx(ref utsname_osx);
                arch   = utsname_osx.machine;
            }
            else
            {
                // Linux
                var utsname_linux = new utsname_linux();
                result = uname_linux(ref utsname_linux);
                arch   = utsname_linux.machine;

                LinuxArchitecture  = utsname_linux.machine;
                LinuxKernelVersion = utsname_linux.version;
            }

            if (result == IntPtr.Zero && (arch.StartsWith("aarch") || arch.StartsWith("arm")))
            {
                current |= Platform.ARM;
            }
        }
        else
        {
            // Detect ARM based on PE info or uname.
            typeof(object).Module.GetPEKind(out var peKind, out var machine);
            if (machine == (ImageFileMachine)0x01C4 /* ARM, .NET Framework 4.5 */)
            {
                current |= Platform.ARM;
            }
        }

        PlatformHelper.Current = current;
    }
示例#2
0
 private static extern bool RtlGetVersion(ref WindowsOSVersionInfoExW versionInfo);