Files
FSI.BT.IR.Tools/RoboSharp/VersionManager.cs
Stephan Maier 647f938eee v1.2
2024-08-27 08:10:27 +02:00

133 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
namespace RoboSharp
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public static class VersionManager
{
public enum VersionCheckType
{
UseRtlGetVersion,
UseWMI
}
public static VersionCheckType VersionCheck { get; set; } = VersionManager.VersionCheckType.UseRtlGetVersion;
private static double? version;
public static double Version
{
get
{
if (version == null)
{
if (VersionCheck == VersionCheckType.UseWMI)
{
var v = GetOsVersion();
version = GetOsVersionNumber(v);
return version.Value;
}
else
{
var osVersionInfo = new OSVERSIONINFOEX { OSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX)) };
RtlGetVersion(ref osVersionInfo);
var versionString = $"{osVersionInfo.MajorVersion}.{osVersionInfo.MinorVersion}{osVersionInfo.BuildNumber}";
version = GetOsVersionNumber(versionString);
return version.Value;
}
}
else
{
return version.Value;
}
}
}
static VersionManager()
{
System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
customCulture.NumberFormat.NumberDecimalSeparator = ".";
System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;
}
private static string GetOsVersion()
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
using (var session = Microsoft.Management.Infrastructure.CimSession.Create("."))
{
var win32OperatingSystemCimInstance = session.QueryInstances("root\\cimv2", "WQL", "SELECT Version FROM Win32_OperatingSystem").FirstOrDefault();
if (win32OperatingSystemCimInstance?.CimInstanceProperties["Version"] != null)
{
return win32OperatingSystemCimInstance.CimInstanceProperties["Version"].Value.ToString();
}
}
#endif
#if NET40_OR_GREATER
using (System.Management.ManagementObjectSearcher objMOS = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem"))
{
foreach (System.Management.ManagementObject objManagement in objMOS.Get())
{
var version = objManagement.GetPropertyValue("Version");
if (version != null)
{
return version.ToString();
}
}
}
#endif
return Environment.OSVersion.Version.ToString();
}
private static double GetOsVersionNumber(string version)
{
if (version.IsNullOrWhiteSpace())
return 0;
var segments = version.Split(new char[] { '.' });
var major = Convert.ToDouble(segments[0]);
var otherSegments = segments.Skip(1).ToArray();
var dec = Convert.ToDouble("." + string.Join("", otherSegments), CultureInfo.InvariantCulture);
return major + dec;
}
/// <summary>
/// taken from https://stackoverflow.com/a/49641055
/// </summary>
/// <param name="versionInfo"></param>
/// <returns></returns>
[SecurityCritical]
[DllImport("ntdll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern int RtlGetVersion(ref OSVERSIONINFOEX versionInfo);
[StructLayout(LayoutKind.Sequential)]
private struct OSVERSIONINFOEX
{
// The OSVersionInfoSize field must be set to Marshal.SizeOf(typeof(OSVERSIONINFOEX))
internal int OSVersionInfoSize;
internal int MajorVersion;
internal int MinorVersion;
internal int BuildNumber;
internal int PlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string CSDVersion;
internal ushort ServicePackMajor;
internal ushort ServicePackMinor;
internal short SuiteMask;
internal byte ProductType;
internal byte Reserved;
}
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}