// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.Extensions.Configuration;
using Microsoft.Win32;
namespace EpicGames.Core
{
///
/// Configuration source which reads values from the Registry on Windows
///
[SupportedOSPlatform("windows")]
public class RegistryConfigurationSource : IConfigurationSource
{
readonly RegistryKey _baseKey;
readonly string _keyPath;
readonly string _baseConfigName;
readonly Func? _filter;
///
/// Constructor
///
/// Hive to resolve keyPath relative to
/// Path within the registry to enumerate
/// Prefix for returned configuration values
/// Optional filter for keys to include
public RegistryConfigurationSource(RegistryKey baseKey, string keyPath, string baseConfigName, Func? filter = null)
{
_baseKey = baseKey;
_keyPath = keyPath;
_baseConfigName = baseConfigName;
_filter = filter;
}
///
/// Get the registry key used
///
///
public string GetRegistryKey() => _baseKey + "\\" + _keyPath;
///
public IConfigurationProvider Build(IConfigurationBuilder builder)
=> new RegistryConfigProvider(_baseKey, _keyPath, _baseConfigName, _filter);
}
class RegistryConfigProvider : ConfigurationProvider
{
readonly RegistryKey _baseKey;
readonly string _keyPath;
readonly string _baseConfigName;
readonly Func? _filter;
public RegistryConfigProvider(RegistryKey baseKey, string keyPath, string baseConfigName, Func? filter)
{
_baseKey = baseKey;
_keyPath = keyPath;
_baseConfigName = baseConfigName;
_filter = filter;
}
public override void Load()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Dictionary data = [];
GetValues(_baseKey, _keyPath, _baseConfigName, _filter, data);
Data = data;
}
}
[SupportedOSPlatform("windows")]
static void GetValues(RegistryKey baseKey, string keyPath, string baseConfigName, Func? filter, Dictionary data)
{
using RegistryKey? registryKey = baseKey.OpenSubKey(keyPath);
if (registryKey != null)
{
string[] subKeyNames = registryKey.GetSubKeyNames();
foreach (string subKeyName in subKeyNames)
{
GetValues(registryKey, subKeyName, $"{baseConfigName}:{subKeyName}", filter, data);
}
string[] valueNames = registryKey.GetValueNames();
foreach (string valueName in valueNames)
{
object? value = registryKey.GetValue(valueName);
if (value != null)
{
string name = $"{baseConfigName}:{valueName}";
if (filter == null || filter(name))
{
data[name] = value.ToString();
}
}
}
}
}
}
}