diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-08-23 18:45:54 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-08-23 18:45:54 -0400 |
commit | 625c41c0ea39bb2af37ece7865098cf2f6d38471 (patch) | |
tree | 214320c647e61fe313ca316c1c1134d8c994a67f /src/SMAPI.Toolkit/Framework | |
parent | fd3bc77d8183070ca338d6a2702edeea7245b5bf (diff) | |
download | SMAPI-625c41c0ea39bb2af37ece7865098cf2f6d38471.tar.gz SMAPI-625c41c0ea39bb2af37ece7865098cf2f6d38471.tar.bz2 SMAPI-625c41c0ea39bb2af37ece7865098cf2f6d38471.zip |
move file for upcoming change
Diffstat (limited to 'src/SMAPI.Toolkit/Framework')
-rw-r--r-- | src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs new file mode 100644 index 00000000..1e490448 --- /dev/null +++ b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs @@ -0,0 +1,170 @@ +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +#if SMAPI_FOR_WINDOWS +using System.Management; +#endif +using System.Runtime.InteropServices; + +namespace StardewModdingAPI.Toolkit.Utilities +{ + /// <summary>Provides methods for fetching environment information.</summary> + public static class EnvironmentUtility + { + /********* + ** Fields + *********/ + /// <summary>The cached platform.</summary> + private static Platform? CachedPlatform; + + /// <summary>Get the OS name from the system uname command.</summary> + /// <param name="buffer">The buffer to fill with the resulting string.</param> + [DllImport("libc")] + static extern int uname(IntPtr buffer); + + + /********* + ** Public methods + *********/ + /// <summary>Detect the current OS.</summary> + public static Platform DetectPlatform() + { + return EnvironmentUtility.CachedPlatform ??= EnvironmentUtility.DetectPlatformImpl(); + } + + + /// <summary>Get the human-readable OS name and version.</summary> + /// <param name="platform">The current platform.</param> + [SuppressMessage("ReSharper", "EmptyGeneralCatchClause", Justification = "Error suppressed deliberately to fallback to default behaviour.")] + public static string GetFriendlyPlatformName(Platform platform) + { +#if SMAPI_FOR_WINDOWS + try + { + return new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem") + .Get() + .Cast<ManagementObject>() + .Select(entry => entry.GetPropertyValue("Caption").ToString()) + .FirstOrDefault(); + } + catch { } +#endif + + string name = Environment.OSVersion.ToString(); + switch (platform) + { + case Platform.Android: + name = $"Android {name}"; + break; + + case Platform.Mac: + name = $"MacOS {name}"; + break; + } + return name; + } + + /// <summary>Get the name of the Stardew Valley executable.</summary> + /// <param name="platform">The current platform.</param> + public static string GetExecutableName(Platform platform) + { + return platform == Platform.Windows + ? "Stardew Valley.exe" + : "StardewValley.exe"; + } + + /// <summary>Get whether the platform uses Mono.</summary> + /// <param name="platform">The current platform.</param> + public static bool IsMono(this Platform platform) + { + return platform == Platform.Linux || platform == Platform.Mac; + } + + + /********* + ** Private methods + *********/ + /// <summary>Detect the current OS.</summary> + private static Platform DetectPlatformImpl() + { + switch (Environment.OSVersion.Platform) + { + case PlatformID.MacOSX: + return Platform.Mac; + + case PlatformID.Unix when EnvironmentUtility.IsRunningAndroid(): + return Platform.Android; + + case PlatformID.Unix when EnvironmentUtility.IsRunningMac(): + return Platform.Mac; + + case PlatformID.Unix: + return Platform.Linux; + + default: + return Platform.Windows; + } + } + + /// <summary>Detect whether the code is running on Android.</summary> + /// <remarks> + /// This code is derived from https://stackoverflow.com/a/47521647/262123. It detects Android by calling the + /// <c>getprop</c> system command to check for an Android-specific property. + /// </remarks> + private static bool IsRunningAndroid() + { + using Process process = new Process + { + StartInfo = + { + FileName = "getprop", + Arguments = "ro.build.user", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + + try + { + process.Start(); + string output = process.StandardOutput.ReadToEnd(); + return !string.IsNullOrWhiteSpace(output); + } + catch + { + return false; + } + } + + /// <summary>Detect whether the code is running on Mac.</summary> + /// <remarks> + /// This code is derived from the Mono project (see System.Windows.Forms/System.Windows.Forms/XplatUI.cs). It detects Mac by calling the + /// <c>uname</c> system command and checking the response, which is always 'Darwin' for MacOS. + /// </remarks> + private static bool IsRunningMac() + { + IntPtr buffer = IntPtr.Zero; + try + { + buffer = Marshal.AllocHGlobal(8192); + if (EnvironmentUtility.uname(buffer) == 0) + { + string os = Marshal.PtrToStringAnsi(buffer); + return os == "Darwin"; + } + return false; + } + catch + { + return false; // default to Linux + } + finally + { + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal(buffer); + } + } + } +} |