using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Vanara.Collections;
using Vanara.Extensions;
using Vanara.InteropServices;
using Vanara.PInvoke;
using static Vanara.PInvoke.Kernel32;
using static Vanara.PInvoke.PowrProf;
namespace Vanara.Diagnostics
{
/// Indicates the status of the battery.
public enum BatteryStatus
{
/// The battery or battery controller is not present.
NotPresent,
/// The battery is discharging.
Discharging,
/// The battery is idle.
Idle,
/// The battery is charging.
Charging
}
/// Specifies the status of battery saver.
public enum EnergySaverStatus
{
/// Battery saver is off permanently or the device is plugged in.
Disabled,
/// Battery saver is off now, but ready to turn on automatically.
Off,
/// Battery saver is on. Save energy where possible.
On
}
[Flags]
public enum PowerCapabilities
{
/// There is a system power button.
PowerButtonPresent = 1 << 0,
/// There is a system sleep button.
SleepButtonPresent = 1 << 1,
/// There is a lid switch.
LidPresent = 1 << 2,
/// The operating system supports sleep state S1.
SystemS1 = 1 << 3,
/// The operating system supports sleep state S2.
SystemS2 = 1 << 4,
/// The operating system supports sleep state S3.
SystemS3 = 1 << 5,
/// The operating system supports sleep state S4 (hibernation).
SystemS4 = 1 << 6,
/// The operating system supports power off state S5 (soft off).
SystemS5 = 1 << 7,
/// The system hibernation file is present.
HiberFilePresent = 1 << 8,
/// The system supports wake capabilities.
FullWake = 1 << 9,
/// The system supports video display dimming capabilities.
VideoDimPresent = 1 << 10,
/// The system supports APM BIOS power management features.
ApmPresent = 1 << 11,
/// There is an uninterruptible power supply (UPS).
UpsPresent = 1 << 12,
/// The system supports thermal zones.
ThermalControl = 1 << 13,
/// The system supports processor throttling.
ProcessorThrottle = 1 << 14,
/// The system supports the hybrid sleep state.
FastSystemS4 = 1 << 15,
///
/// The system supports fast startup (aka: hiberboot, hybrid boot, or hybrid shutdown) which is a setting that helps your PC start up
/// faster after shutdown.
///
Hiberboot = 1 << 16,
///
/// The platform has support for ACPI wake alarm devices. For more details on wake alarm devices, please see the ACPI specification
/// section 9.18.
///
WakeAlarmPresent = 1 << 17,
/// The system supports the S0 low power idle model.
AoAc = 1 << 18,
/// The system supports allowing the removal of power to fixed disk devices.
DiskSpinDown = 1 << 19,
///
AoAcConnectivitySupported = 1 << 20,
/// There are one or more batteries in the system.
SystemBatteriesPresent = 1 << 21,
/// The system batteries are short-term. Short-term batteries are used in uninterruptible power supplies (UPS).
BatteriesAreShortTerm = 1 << 22
}
/// Represents the device's power supply status.
public enum PowerSupplyStatus
{
/// The device has no power supply.
NotPresent,
/// The device has an inadequate power supply.
Inadequate,
/// The device has an adequate power supply.
Adequate
}
///
/// Provides access to information about a device's battery and power supply status and configuration. This extends the capabilities
/// Windows.System.Power.PowerManager to include more detail, schemes and devices.
///
public static class PowerManager
{
/*
public static event EventHandler BatteryStatusChanged;
public static event EventHandler EnergySaverStatusChanged;
public static event EventHandler PowerSupplyStatusChanged;
public static event EventHandler RemainingChargePercentChanged;
public static event EventHandler RemainingDischargeTimeChanged;
*/
/// Gets the device's battery status.
/// Returns a value.
public static BatteryStatus BatteryStatus
{
get
{
var s = GetStatus();
switch (s.BatteryFlag)
{
case BATTERY_STATUS.BATTERY_CHARGING:
return BatteryStatus.Charging;
case BATTERY_STATUS.BATTERY_NONE:
return BatteryStatus.NotPresent;
default:
return s.ACLineStatus == AC_STATUS.AC_OFFLINE ? BatteryStatus.Discharging : BatteryStatus.Idle;
}
}
}
/// Gets flags indicating the system's power capabilities.
/// Returns a value.
public static PowerCapabilities DeviceCapabilities
{
get
{
var c = GetCapabilities();
PowerCapabilities ret = 0;
if (c.PowerButtonPresent) ret |= PowerCapabilities.PowerButtonPresent;
if (c.SleepButtonPresent) ret |= PowerCapabilities.SleepButtonPresent;
if (c.LidPresent) ret |= PowerCapabilities.LidPresent;
if (c.SystemS1) ret |= PowerCapabilities.SystemS1;
if (c.SystemS2) ret |= PowerCapabilities.SystemS2;
if (c.SystemS3) ret |= PowerCapabilities.SystemS3;
if (c.SystemS4) ret |= PowerCapabilities.SystemS4;
if (c.SystemS5) ret |= PowerCapabilities.SystemS5;
if (c.HiberFilePresent) ret |= PowerCapabilities.HiberFilePresent;
if (c.FullWake) ret |= PowerCapabilities.FullWake;
if (c.VideoDimPresent) ret |= PowerCapabilities.VideoDimPresent;
if (c.ApmPresent) ret |= PowerCapabilities.ApmPresent;
if (c.UpsPresent) ret |= PowerCapabilities.UpsPresent;
if (c.ThermalControl) ret |= PowerCapabilities.ThermalControl;
if (c.ProcessorThrottle) ret |= PowerCapabilities.ProcessorThrottle;
if (c.FastSystemS4) ret |= PowerCapabilities.FastSystemS4;
if (c.Hiberboot) ret |= PowerCapabilities.Hiberboot;
if (c.WakeAlarmPresent) ret |= PowerCapabilities.WakeAlarmPresent;
if (c.AoAc) ret |= PowerCapabilities.AoAc;
if (c.DiskSpinDown) ret |= PowerCapabilities.DiskSpinDown;
if (c.AoAcConnectivitySupported) ret |= PowerCapabilities.AoAcConnectivitySupported;
if (c.SystemBatteriesPresent) ret |= PowerCapabilities.SystemBatteriesPresent;
if (c.BatteriesAreShortTerm) ret |= PowerCapabilities.BatteriesAreShortTerm;
return ret;
}
}
/// Gets the device's battery saver status, indicating when to save energy.
/// Returns a value.
public static EnergySaverStatus EnergySaverStatus
{
get
{
var s = GetStatus();
return s.ACLineStatus == AC_STATUS.AC_ONLINE || s.BatteryFlag == BATTERY_STATUS.BATTERY_NONE ? EnergySaverStatus.Disabled : (s.SystemStatusFlag == 0 ? EnergySaverStatus.Off : EnergySaverStatus.On);
}
}
/// Gets a value indicating whether the system is on AC power (plugged in).
/// if on AC power; otherwise, .
public static bool OnACPower => GetStatus().ACLineStatus == AC_STATUS.AC_ONLINE;
/// Indicates the OEM's preferred power management profile for this device.
public static POWER_PLATFORM_ROLE PlatformRole => PInvokeClient.Windows8.IsPlatformSupported() ? PowerDeterminePlatformRoleEx(PowerPlatformRoleVersion.POWER_PLATFORM_ROLE_V2) : PowerDeterminePlatformRole();
/// A collection of the powered devices on the system. Filters on this list can be set as properties.
/// Returns a value.
public static PoweredDeviceCollection PoweredDevices { get; } = new PoweredDeviceCollection();
/// Gets the device's power supply status.
/// Returns a value.
public static PowerSupplyStatus PowerSupplyStatus
{
get
{
var s = GetStatus();
switch (s.ACLineStatus)
{
case AC_STATUS.AC_ONLINE:
return PowerSupplyStatus.Adequate;
case AC_STATUS.AC_LINE_BACKUP_POWER:
return PowerSupplyStatus.Inadequate;
default:
return PowerSupplyStatus.NotPresent;
}
}
}
/// Gets the total percentage of charge remaining from all batteries connected to the device.
/// Returns a value from 0 to 100, or if the status is unknown.
public static int? RemainingChargePercent { get { var p = GetStatus().BatteryLifePercent; return p == 255 ? (int?)null : p; } }
/// Gets the total runtime remaining from all batteries connected to the device.
///
/// The total runtime remaining from all batteries connected to the device, or if the status is unknown or
/// connected to AC power.
///
public static TimeSpan? RemainingDischargeTime { get { var s = GetStatus().BatteryLifeTime; return s == uint.MaxValue ? (TimeSpan?)null : TimeSpan.FromSeconds(s); } }
/// Gets the collection of all power schemes on this device.
/// Returns a value.
public static PowerSchemeCollection Schemes { get; } = new PowerSchemeCollection();
internal static string NameForGuid(Guid guid) => typeof(PowrProf).GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(i => i.FieldType == typeof(Guid) && guid.Equals(i.GetValue(null)))?.Name;
private static SYSTEM_POWER_CAPABILITIES GetCapabilities() => GetPwrCapabilities(out var c) ? c : default;
private static SYSTEM_POWER_STATUS GetStatus() => GetSystemPowerStatus(out var s) ? s : default;
}
/// Represents a device on the system that has power requirements.
public class PoweredDevice
{
private readonly bool hw;
internal PoweredDevice(string id, bool isHW)
{
Id = id;
hw = isHW;
}
/// Gets or sets the identifier for the device.
/// The identifier.
public string Id { get; protected set; }
/// Gets or sets a value indicating whether the device is wake enabled.
/// if wake enabled; otherwise, .
public bool WakeEnabled
{
get => PoweredDeviceCollection.GetEnumValues((hw ? PDQUERY.DEVICEPOWER_HARDWAREID : 0) | PDQUERY.DEVICEPOWER_FILTER_WAKEENABLED).Any(s => s == Id);
set => DevicePowerSetDeviceState(Id, value ? PDSET.DEVICEPOWER_SET_WAKEENABLED : PDSET.DEVICEPOWER_CLEAR_WAKEENABLED);
}
///
public override string ToString() => Id;
}
/// Retrieves the list, optionally filtered, of the powered devices on the system.
///
public class PoweredDeviceCollection : VirtualDictionary
{
private static Finalizer finalizer;
internal PoweredDeviceCollection() : base(true)
{
}
///
public override ICollection Keys => GetEnumValues(PDQUERY).ToList();
/// Gets or sets a value indicating whether to display only devices that are currently present in the system.
/// to retrieve only present devices; otherwise, .
public bool OnlyPresentDevices { get; set; }
/// Gets or sets a value indicating whether to display only devices that are wake-enabled.
/// if to retrieve only wake enabled devices; otherwise, .
public bool OnlyWakeEnabledDevices { get; set; }
/// Gets or sets a value indicating whether to display the hardware identifier rather than a friendly name.
///
/// to display the hardware identifier; otherwise, to display the friendly name.
///
public bool UseHardwareId { get; set; }
///
public override ICollection Values => GetEnumValues(PDQUERY).Select(s => new PoweredDevice(s, UseHardwareId)).ToList();
///
protected override IEnumerable> Items => GetEnumValues(PDQUERY).Select(s => new KeyValuePair(s, new PoweredDevice(s, UseHardwareId)));
private PDQUERY PDQUERY => (UseHardwareId ? PDQUERY.DEVICEPOWER_HARDWAREID : 0) | (OnlyPresentDevices ? PDQUERY.DEVICEPOWER_FILTER_DEVICES_PRESENT : 0) | (OnlyWakeEnabledDevices ? PDQUERY.DEVICEPOWER_FILTER_WAKEENABLED : 0);
///
public override bool TryGetValue(string key, out PoweredDevice value)
{
var ret = GetEnumValues(UseHardwareId ? PDQUERY.DEVICEPOWER_HARDWAREID : 0).Contains(key);
value = ret ? new PoweredDevice(key, UseHardwareId) : null;
return ret;
}
internal static IEnumerable GetEnumValues(PDQUERY filter = 0, PDCAP flags = 0)
{
const uint bufSz = 1024;
ValidateOpened();
var sz = bufSz;
var sb = new StringBuilder((int)sz / 2, (int)sz / 2);
for (var i = 0U; ; i++)
{
sb.Clear();
if (DevicePowerEnumDevices(i, filter, flags, sb, ref sz))
yield return sb.ToString();
else
break;
}
}
private static void ValidateOpened()
{
if (finalizer is null) finalizer = new Finalizer();
}
private class Finalizer
{
internal Finalizer() => DevicePowerOpen();
~Finalizer() => DevicePowerClose();
}
}
/// Represents a system power scheme (power plan).
public class PowerScheme : IEquatable, IEquatable
{
/// The well-known, system defined Balance (or Typical) power scheme with fairly aggressive power savings measures.
public static readonly PowerScheme Balanced = new PowerScheme(GUID_TYPICAL_POWER_SAVINGS);
/// The well-known, system defined High Performance (or Minimum) power scheme with almost no power savings measures.
public static readonly PowerScheme HighPerformance = new PowerScheme(GUID_MIN_POWER_SAVINGS);
///
/// The well-known, system defined Power Saver (or Max) power scheme with very aggressive power savings measures to help stretch
/// battery life.
///
public static readonly PowerScheme PowerSaver = new PowerScheme(GUID_MAX_POWER_SAVINGS);
internal PowerScheme(Guid g)
{
Guid = g;
Groups = new PowerSchemeGroupCollection(g);
}
/// Gets the active power scheme for the system.
/// Returns a value for the active scheme.
public static PowerScheme Active => PowerGetActiveScheme(out var g).Succeeded ? new PowerScheme(g) : throw new SystemException();
/// Gets the variable name of the GUID defined in the Windows SDK for this scheme.
/// The API based variable name.
public string ApiName => PowerManager.NameForGuid(Guid);
/// Gets or sets the description of the scheme.
/// The description.
public string Description
{
get => PowerReadDescription(Guid);
set => PowerWriteDescription(Guid, null, null, value).ThrowIfFailed();
}
/// Gets the subgroups defined for this scheme.
/// Returns a value.
public PowerSchemeGroupCollection Groups { get; }
/// Gets or sets a value indicating whether this scheme is the active scheme for the system.
/// if this instance is active; otherwise, .
public bool IsActive
{
get => PowerGetActiveScheme(out var g).Succeeded && Guid.Equals(g);
set => PowerSetActiveScheme(default, Guid).ThrowIfFailed();
}
/// Gets or sets the friendly name of the scheme.
/// The friendly name.
public string Name
{
get => PowerReadFriendlyName(Guid);
set => PowerWriteFriendlyName(Guid, null, null, value).ThrowIfFailed();
}
/// Gets the underlying GUID for the scheme.
/// Returns a value.
protected internal Guid Guid { get; }
/// Returns a duplicates this scheme that can be edited and set as the new active scheme.
/// An editable duplicate of the current scheme.
public PowerScheme Duplicate()
{
PowerDuplicateScheme(default, Guid, out var h).ThrowIfFailed();
return new PowerScheme(h.ToStructure());
}
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// if the specified is equal to this instance; otherwise, .
public bool Equals(Guid other) => Guid.Equals(other);
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// if the specified is equal to this instance; otherwise, .
public bool Equals(PowerScheme other) => !(other is null) && Equals(other.Guid);
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// if the specified is equal to this instance; otherwise, .
public override bool Equals(object obj) => obj is Guid g ? Equals(g) : obj is PowerScheme s && Equals(s);
/// Returns a hash code for this instance.
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
public override int GetHashCode() => Guid.GetHashCode();
//public System.Drawing.Icon Icon { get; set; }
}
/// Represents a collection of all the power schemes available on the system.
///
public class PowerSchemeCollection : VirtualDictionary
{
internal PowerSchemeCollection() : base(!CanUserWritePwrScheme())
{
}
///
public override ICollection Keys => PowerEnumerate(null, null).ToList();
/// Imports a power scheme from a file.
/// The path to a power scheme backup file created by PowerCfg.Exe /Export.
/// A derived from the file.
public static PowerScheme ImportFromFile(string importFilePath)
{
PowerImportPowerScheme(default, importFilePath, out var memG).ThrowIfFailed();
return new PowerScheme(memG.ToStructure());
}
///
/// Replaces the default power schemes with the current user's power schemes. This allows an administrator to change the default
/// power schemes for the system. Replacing the default schemes enables users to use the Restore Defaults option in the
/// Control Panel Power Options application to restore customized power scheme defaults instead of the original Windows power
/// scheme defaults.
///
/// The caller must be a member of the local Administrators group.
public static void ReplaceDefaultPowerSchemes() => PowerReplaceDefaultPowerSchemes().ThrowIfFailed();
///
/// Replaces the power schemes for the system with default power schemes. All current power schemes and settings are deleted and
/// replaced with the default system power schemes.
///
/// The caller must be a member of the local Administrators group.
public static void RestoreDefaultPowerSchemes() => PowerRestoreDefaultPowerSchemes().ThrowIfFailed();
///
public override bool Remove(Guid key) => PowerDeleteScheme(default, key).Succeeded;
///
public override bool TryGetValue(Guid key, out PowerScheme value)
{
value = new PowerScheme(key); return true;
}
// public static POWER_POLICY ActivePowerPolicy => GetCurrentPowerPolicies(out var _, out var p) ? p : default; public static
// GLOBAL_POWER_POLICY GlobalPowerPolicy => GetCurrentPowerPolicies(out var p, out var _) ? p : default;
}
/// Represents a subgroup of a system power scheme (power plan).
public class PowerSchemeGroup
{
protected Guid scheme, subgroup;
internal PowerSchemeGroup(Guid scheme, Guid group)
{
this.scheme = scheme;
subgroup = group;
Settings = new PowerSchemeSettingCollection(scheme, subgroup);
}
/// Gets the variable name of the GUID defined in the Windows SDK for this subgroup.
/// The API based variable name.
public string ApiName => PowerManager.NameForGuid(subgroup);
/// Gets or sets the description of the subgroup.
/// The description.
public string Description
{
get => PowerReadDescription(scheme, subgroup);
set => PowerWriteDescription(scheme, subgroup, null, value).ThrowIfFailed();
}
/// Gets or sets the friendly name of the subgroup.
/// The friendly name.
public string Name
{
get => PowerReadFriendlyName(scheme, subgroup);
set => PowerWriteFriendlyName(scheme, subgroup, null, value).ThrowIfFailed();
}
/// Gets the settings defined for this subgroup.
/// Returns a value.
public PowerSchemeSettingCollection Settings { get; }
}
/// Represents a collection of all the subgroups available under a power scheme on the system.
public class PowerSchemeGroupCollection : VirtualDictionary
{
protected Guid scheme;
internal PowerSchemeGroupCollection(Guid scheme) : base(false) => this.scheme = scheme;
///
public override ICollection Keys => PowerEnumerate(scheme, null).Concat(new[] { NO_SUBGROUP_GUID }).ToList();
///
public override bool TryGetValue(Guid key, out PowerSchemeGroup value)
{
value = new PowerSchemeGroup(scheme, key); return true;
}
}
/// Represents a setting on a subgroup.
public class PowerSchemeSetting
{
protected Guid scheme, subgroup, setting;
internal PowerSchemeSetting(Guid scheme, Guid group, Guid setting)
{
this.scheme = scheme;
subgroup = group;
this.setting = setting;
}
private delegate Win32Error IdxWriter(HKEY rootSystemPowerKey, in Guid schemePersonalityGuid, in Guid subGroupOfPowerSettingsGuid, in Guid powerSettingGuid, uint index);
/// Retrieves the AC power value for the specified power setting.
/// Returns the data value.
public object ACValue
{
get
{
var sz = 0U;
PowerReadACValue(default, scheme, subgroup, setting, out var regType, IntPtr.Zero, ref sz).ThrowIfFailed();
using (var mem = new SafeHGlobalHandle((int)sz))
{
PowerReadACValue(default, scheme, subgroup, setting, out regType, (IntPtr)mem, ref sz).ThrowIfFailed();
return regType.GetValue((IntPtr)mem, sz);
}
}
}
/// Gets or sets the default AC index of the specified power setting.
/// The default AC index.
public int ACValueDefaultIndex
{
get => PowerReadACDefaultIndex(default, scheme, subgroup, setting, out var i).Succeeded ? (int)i : -1;
set => WriteIndex(PowerWriteACDefaultIndex, value);
}
/// Gets or sets the AC index of the specified power setting.
/// The AC index.
public int ACValueIndex
{
get => PowerReadACValueIndex(default, scheme, subgroup, setting, out var i).Succeeded ? (int)i : -1;
set => WriteIndex(PowerWriteACValueIndex, value);
}
/// Gets the variable name of the GUID defined in the Windows SDK for this setting.
/// The API based variable name.
public string ApiName => PowerManager.NameForGuid(setting);
/// Retrieves the DC power value for the specified power setting.
/// Returns the data value.
public object DCValue
{
get
{
var sz = 0U;
PowerReadDCValue(default, scheme, subgroup, setting, out var regType, IntPtr.Zero, ref sz).ThrowIfFailed();
using (var mem = new SafeHGlobalHandle((int)sz))
{
PowerReadDCValue(default, scheme, subgroup, setting, out regType, (IntPtr)mem, ref sz).ThrowIfFailed();
return regType.GetValue((IntPtr)mem, sz);
}
}
}
/// Gets or sets the default DC index of the specified power setting.
/// The default DC index.
public int DCValueDefaultIndex
{
get => PowerReadDCDefaultIndex(default, scheme, subgroup, setting, out var i).Succeeded ? (int)i : -1;
set => WriteIndex(PowerWriteDCDefaultIndex, value);
}
/// Gets or sets the DC index of the specified power setting.
/// The DC index.
public int DCValueIndex
{
get => PowerReadDCValueIndex(default, scheme, subgroup, setting, out var i).Succeeded ? (int)i : -1;
set => WriteIndex(PowerWriteDCValueIndex, value);
}
/// Gets or sets the description of the setting.
/// The description.
public string Description
{
get => PowerReadDescription(scheme, subgroup, setting);
set { PowerWriteDescription(scheme, subgroup, setting, value).ThrowIfFailed(); PowerSetActiveScheme(default, scheme).ThrowIfFailed(); }
}
public bool IsRange => PowerIsSettingRangeDefined(subgroup, setting);
/// Gets or sets the friendly name of the setting.
/// The friendly name.
public string Name
{
get => PowerReadFriendlyName(scheme, subgroup, setting);
set { PowerWriteFriendlyName(scheme, subgroup, setting, value).ThrowIfFailed(); PowerSetActiveScheme(default, scheme).ThrowIfFailed(); }
}
/// Gets the possible values for this setting.
/// Returns a value.
public IEnumerable<(object value, string name, string description)> PossibleValues
{
get
{
if (IsRange) yield break;
for (var i = 0U; ; i++)
{
var err = FunctionHelper.CallMethodWithStrBuf((StringBuilder sb, ref uint ssz) => PowerReadPossibleFriendlyName(default, subgroup, setting, i, sb, ref ssz), out var name, (ssz, r) => ssz > 0);
if (err.Failed)
break;
err = FunctionHelper.CallMethodWithStrBuf((StringBuilder sb, ref uint ssz) => PowerReadPossibleDescription(default, subgroup, setting, i, sb, ref ssz), out var desc, (ssz, r) => ssz > 0);
if (err.Failed)
break;
var sz = 0U;
object obj = null;
err = PowerReadPossibleValue(default, subgroup, setting, out var regType, i, IntPtr.Zero, ref sz);
if (err.Succeeded)
{
using (var mem = new SafeHGlobalHandle((int)sz))
{
err = PowerReadPossibleValue(default, subgroup, setting, out regType, i, (IntPtr)mem, ref sz);
if (err.Failed)
break;
obj = regType.GetValue((IntPtr)mem, sz);
}
}
yield return (obj, name, desc);
}
}
}
/// Gets or sets the range information for this setting.
/// The range detail (min/max value, increment and unit specifier.
/// Setting is not a range value.
public (uint min, uint max, uint increment, string unitsSpecifier) Range
{
get
{
try
{
if (IsRange)
{
PowerReadValueMin(default, subgroup, setting, out var min).ThrowIfFailed();
PowerReadValueMax(default, subgroup, setting, out var max).ThrowIfFailed();
PowerReadValueIncrement(default, subgroup, setting, out var incr).ThrowIfFailed();
FunctionHelper.CallMethodWithStrBuf((StringBuilder sb, ref uint sz) => PowerReadValueUnitsSpecifier(default, subgroup, setting, sb, ref sz), out var spec, (sz, r) => sz > 0).ThrowIfFailed();
return (min, max, incr, spec);
}
}
catch { }
return (0, 0, 0, null);
}
set
{
if (!IsRange) throw new InvalidOperationException("Setting is not a range value.");
PowerWriteValueMin(default, subgroup, setting, value.min).ThrowIfFailed();
PowerWriteValueMax(default, subgroup, setting, value.max).ThrowIfFailed();
PowerWriteValueIncrement(default, subgroup, setting, value.increment).ThrowIfFailed();
PowerWriteValueUnitsSpecifier(default, subgroup, setting, value.unitsSpecifier, (uint)((value.unitsSpecifier?.Length + 1) * 2 ?? 0)).ThrowIfFailed();
PowerSetActiveScheme(default, scheme).ThrowIfFailed();
}
}
private void WriteIndex(IdxWriter func, int value)
{
func(default, scheme, subgroup, setting, unchecked((uint)value)).ThrowIfFailed();
PowerSetActiveScheme(default, scheme).ThrowIfFailed();
}
}
/// Represents a collection of all settings for a subgroup and power scheme on the system.
public class PowerSchemeSettingCollection : VirtualDictionary
{
protected Guid scheme, subgroup;
internal PowerSchemeSettingCollection(Guid scheme, Guid subgroup) : base(false)
{
this.scheme = scheme; this.subgroup = subgroup;
}
///
public override ICollection Keys => PowerEnumerate(scheme, subgroup).ToList();
///
public override bool TryGetValue(Guid key, out PowerSchemeSetting value)
{
value = new PowerSchemeSetting(scheme, subgroup, key); return true;
}
}
}