Refactor Windows version check, enable warning (resolves #2972, #3194)

This commit is contained in:
YoshiRulz 2022-06-11 05:57:14 +10:00
parent a98e3f3610
commit 5878555221
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
2 changed files with 46 additions and 30 deletions

View File

@ -685,23 +685,26 @@ namespace BizHawk.Client.EmuHawk
// I would like to trigger a repaint here, but this isn't done yet
};
if (!OSTailoredCode.IsUnixHost && !Config.SkipOutdatedOsCheck)
if (!Config.SkipOutdatedOsCheck && OSTailoredCode.HostWindowsVersion is not null)
{
var (winVersion, win10Release) = OSTailoredCode.HostWindowsVersion.Value;
var (winVersion, win10PlusVersion) = OSTailoredCode.HostWindowsVersion.Value;
var message = winVersion switch
{
OSTailoredCode.WindowsVersion._10 when win10Release < 1909 => $"Quick reminder: version {win10Release} of Windows 10 is no longer supported by Microsoft. EmuHawk will continue to work, but please update to at least 1909 for increased security.",
// OSTailoredCode.WindowsVersion._11 when win10PlusRelease! < new Version(10, 0, 22621) => $"Quick reminder: Your copy of Windows 11 (build {win10PlusRelease.Build}) is no longer supported by Microsoft.\nEmuHawk will probably continue working, but please update to at least 21H2 for increased security.",
OSTailoredCode.WindowsVersion._11 => null,
OSTailoredCode.WindowsVersion._10 when win10PlusVersion! < new Version(10, 0, 19043) => $"Quick reminder: Your copy of Windows 10 (build {win10PlusVersion.Build}) is no longer supported by Microsoft.\nEmuHawk will probably continue working, but please update to at least 21H1 for increased security.",
OSTailoredCode.WindowsVersion._10 => null,
OSTailoredCode.WindowsVersion._8_1 => null, // still CBB
_ => $"Quick reminder: Windows {winVersion.ToString().RemovePrefix('_').Replace("_", ".")} is no longer supported by Microsoft. EmuHawk will continue to work, but please get a new operating system for increased security (either Windows 8.1, Windows 10, or a GNU+Linux distro)."
OSTailoredCode.WindowsVersion._8_1 => "Heads up: Microsoft will stop supporting Windows 8.1 in January 2023, and we'll be doing the same.\nEmuHawk will probably continue working, but please get a new operating system (either Windows 10+ or a GNU+Linux distro).",
_ => $"Quick reminder: Windows {winVersion.ToString().RemovePrefix('_').Replace("_", ".")} is no longer supported by Microsoft.\nEmuHawk will probably continue working, but please get a new operating system for increased security (either Windows 10+ or a GNU+Linux distro)."
};
#if false
if (message != null)
if (message is not null)
{
using var box = new ExceptionBox(message);
box.ShowDialog();
}
#if DEBUG
Console.WriteLine(message);
#else
Load += (_, _) => Config.SkipOutdatedOsCheck = this.ShowMessageBox2($"{message}\n\nSkip this reminder from now on?");
#endif
}
}
}

View File

@ -1,6 +1,7 @@
#nullable enable
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using BizHawk.Common.StringExtensions;
@ -18,37 +19,48 @@ namespace BizHawk.Common
? SimpleSubshell("uname", "-s", "Can't determine OS") == "Darwin" ? DistinctOS.macOS : DistinctOS.Linux
: DistinctOS.Windows;
private static readonly Lazy<(WindowsVersion, int?)?> _HostWindowsVersion = new Lazy<(WindowsVersion, int?)?>(() =>
private static readonly Lazy<(WindowsVersion, Version?)?> _HostWindowsVersion = new(() =>
{
static string GetRegValue(string key)
static string? GetRegValue(string key)
{
using var proc = ConstructSubshell("REG", $@"QUERY ""HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion"" /V {key}");
proc.Start();
return proc.StandardOutput.ReadToEnd().Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new[] { "\t", " " }, StringSplitOptions.RemoveEmptyEntries)[2];
try
{
using var proc = ConstructSubshell("REG", $@"QUERY ""HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion"" /V {key}");
proc.Start();
return proc.StandardOutput.ReadToEnd().Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new[] { "\t", " " }, StringSplitOptions.RemoveEmptyEntries)[2];
}
catch (Exception)
{
// Education edition? Poor Group Policy setup? https://github.com/TASEmulators/BizHawk/issues/2972
return null;
}
}
if (CurrentOS != DistinctOS.Windows) return null;
var rawWinVer = float.Parse(GetRegValue("CurrentVersion"), NumberFormatInfo.InvariantInfo); // contains '.' even when system-wide decimal separator is ','
WindowsVersion winVer; // sorry if this elif chain is confusing, I couldn't be bothered writing and testing float equality --yoshi
if (rawWinVer < 6.0f) winVer = WindowsVersion.XP;
else if (rawWinVer < 6.1f) winVer = WindowsVersion.Vista;
else if (rawWinVer < 6.2f) winVer = WindowsVersion._7;
else if (rawWinVer < 6.3f) winVer = WindowsVersion._8;
else
Version rawWinVer = new(GetRegValue("CurrentVersion") ?? "6.3");
WindowsVersion winVer;
if (rawWinVer >= new Version(6, 3))
{
// 8.1 and 10 are both version 6.3
if (GetRegValue("ProductName").Contains("Windows 10"))
// Win8.1, Win10, and Win11 all have CurrentVersion == "6.3"
if ((GetRegValue("ProductName") ?? "Windows 10").Contains("Windows 10"))
{
return (WindowsVersion._10, int.Parse(GetRegValue("ReleaseId")));
// Win11 has ProductName == "Windows 10 Pro" MICROSOFT WHY https://stackoverflow.com/a/69922526 https://stackoverflow.com/a/70456554
Version win10PlusVer = new(FileVersionInfo.GetVersionInfo(@"C:\Windows\System32\kernel32.dll").FileVersion.SubstringBefore(' '));
return (win10PlusVer < new Version(10, 0, 22000) ? WindowsVersion._10 : WindowsVersion._11, win10PlusVer);
}
// ...else we're on 8.1. Can't be bothered writing code for KB installed check, not that I have a Win8.1 machine to test on anyway, so it gets a free pass --yoshi
// ...else we're on 8.1. Can't be bothered writing code for KB installed check, not that I have a Win8.1 machine to test on anyway, so it gets a free pass (though I suspect comparing against the kernel32.dll version would work here too). --yoshi
winVer = WindowsVersion._8_1;
}
else if (rawWinVer == new Version(6, 2)) winVer = WindowsVersion._8;
else if (rawWinVer == new Version(6, 1)) winVer = WindowsVersion._7;
// in reality, EmuHawk will not run on these OSes, but here they are for posterity
else if (rawWinVer == new Version(6, 0)) winVer = WindowsVersion.Vista;
else /*if (rawWinVer < new Version(6, 0))*/ winVer = WindowsVersion.XP;
return (winVer, null);
});
private static readonly Lazy<bool> _isWSL = new(() => IsUnixHost && SimpleSubshell("uname", "-r", "missing uname?").Contains("microsoft", StringComparison.InvariantCultureIgnoreCase));
public static (WindowsVersion Version, int? Win10Release)? HostWindowsVersion => _HostWindowsVersion.Value;
public static (WindowsVersion Version, Version? Win10PlusVersion)? HostWindowsVersion => _HostWindowsVersion.Value;
public static readonly bool IsUnixHost = CurrentOS != DistinctOS.Windows;
@ -167,7 +179,8 @@ namespace BizHawk.Common
_7,
_8,
_8_1,
_10
_10,
_11,
}
/// <param name="cmd">POSIX <c>$0</c></param>
@ -200,7 +213,7 @@ namespace BizHawk.Common
proc.Start();
var stdout = proc.StandardOutput;
if (stdout.EndOfStream) throw new Exception($"{noOutputMsg} ({cmd} wrote nothing to stdout)");
return stdout.ReadLine();
return stdout.ReadLine()!;
}
}
}