using System;
using System.Collections.Generic;
using System.Linq;
using Flow.Launcher.Plugin.WindowsSettings.Classes;
namespace Flow.Launcher.Plugin.WindowsSettings.Helper
{
///
/// Helper class to easier work with the version of the Windows OS
///
internal static class UnsupportedSettingsHelper
{
private const string _keyPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
private const string _keyNameBuild = "CurrentBuild";
private const string _keyNameBuildNumber = "CurrentBuildNumber";
///
/// Remove all of the given list that are not present on the current used Windows build.
///
/// The list with to filter.
/// A new list with that only contain present Windows settings for this OS.
internal static IEnumerable FilterByBuild(in IEnumerable? settingsList)
{
if (settingsList is null)
{
return Enumerable.Empty();
}
var currentBuild = GetNumericRegistryValue(_keyPath, _keyNameBuild);
var currentBuildNumber = GetNumericRegistryValue(_keyPath, _keyNameBuildNumber);
if (currentBuild != currentBuildNumber)
{
var usedValueName = currentBuild != uint.MinValue ? _keyNameBuild : _keyNameBuildNumber;
var warningMessage =
$"Detecting the Windows version in registry ({_keyPath}) leads to an inconclusive"
+ $" result ({_keyNameBuild}={currentBuild}, {_keyNameBuildNumber}={currentBuildNumber})!"
+ $" For resolving the conflict we use the value of '{usedValueName}'.";
Log.Warn(warningMessage, typeof(UnsupportedSettingsHelper));
}
var currentWindowsBuild = currentBuild != uint.MinValue
? currentBuild
: currentBuildNumber;
var filteredSettingsList = settingsList.Where(found
=> (found.DeprecatedInBuild == null || currentWindowsBuild < found.DeprecatedInBuild)
&& (found.IntroducedInBuild == null || currentWindowsBuild >= found.IntroducedInBuild));
filteredSettingsList = filteredSettingsList.OrderBy(found => found.Name);
return filteredSettingsList;
}
///
/// Return a unsigned numeric value from given registry value name inside the given registry key.
///
/// The registry key.
/// The name of the registry value.
/// A registry value or on error.
private static uint GetNumericRegistryValue(in string registryKey, in string valueName)
{
object? registryValueData;
try
{
registryValueData = Microsoft.Win32.Registry.GetValue(registryKey, valueName, uint.MinValue);
}
catch (Exception exception)
{
Log.Exception(
$"Can't get registry value for '{valueName}'",
exception,
typeof(UnsupportedSettingsHelper));
return uint.MinValue;
}
return uint.TryParse(registryValueData as string, out var buildNumber)
? buildNumber
: uint.MinValue;
}
}
}