Some times you may need to get value of advanced power settings in your application. For example you may want to know after how much idle time, the system will hibernate of sleep. Here in this post I’ll show how you can get those values in C# using different solutions. For example we will get value of Hibernate after setting.
You can get value of advanced power settings values using Windows API, Registry, and WMI. The most important common information for all solutions is some GUID values:
- Power Scheme GUID: Identifier of power plan
- Subgroup GUID: Identifier of a group of the settings
- Power Setting GUID: Identifier of the setting
For example to get value of Hibernate After, you need following GUIDs:
- GUID of Active Plan (You should first find it.)
- GUID of Sleep Sub Group :
238c9fa8-0aad-41ed-83f4-97be242c8f20
- GUID of Hibernate After Setting:
9d7815a6-7ee4-497e-8888-515a05f02364
But how can you find GUID of active plan, sub groups and settings? Any solution which you use, you need to first find GUID of Active Plan programmatically. But other GUIDs you can use constant values. For example, you can run this command in command window having admin privilege:
powercfg -QUERY >c:\poweroptions.txt
Then if you open the file, you will see a list of sub groups and settings and their values:
...
Subgroup GUID: 238c9fa8-0aad-41ed-83f4-97be242c8f20 (Sleep)
GUID Alias: SUB_SLEEP
...
Power Setting GUID: 9d7815a6-7ee4-497e-8888-515a05f02364 (Hibernate after)
GUID Alias: HIBERNATEIDLE
Minimum Possible Setting: 0x00000000
Maximum Possible Setting: 0xffffffff
Possible Settings increment: 0x00000001
Possible Settings units: Seconds
Current AC Power Setting Index: 0x00002a30
Current DC Power Setting Index: 0x00002a30
...
So using the result you can find sub groups GUID and settings GUID. To find more about powercfg
command you can use powercfg /?
.
Using Windows API
There are a couple of power management functions which allows us to read and change advanced power settings. You can use PowerGetActiveScheme
function to get the active power plan, then you can use PowerReadACValue
to get the value which you need.
To do so, first declare:
private static Guid GUID_SLEEP_SUBGROUP =
new Guid("238c9fa8-0aad-41ed-83f4-97be242c8f20");
private static Guid GUID_HIBERNATEIDLE =
new Guid("9d7815a6-7ee4-497e-8888-515a05f02364");
[DllImport("powrprof.dll")]
static extern uint PowerGetActiveScheme(
IntPtr UserRootPowerKey,
ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
IntPtr RootPowerKey,
ref Guid SchemeGuid,
ref Guid SubGroupOfPowerSettingGuid,
ref Guid PowerSettingGuid,
ref int Type,
ref int Buffer,
ref uint BufferSize);
Then find the value this way:
var activePolicyGuidPTR = IntPtr.Zero;
PowerGetActiveScheme(IntPtr.Zero, ref activePolicyGuidPTR);
var activePolicyGuid = Marshal.PtrToStructure<Guid>(activePolicyGuidPTR);
var type = 0;
var value = 0;
var valueSize = 4u;
PowerReadACValue(IntPtr.Zero, ref activePolicyGuid,
ref GUID_SLEEP_SUBGROUP, ref GUID_HIBERNATEIDLE,
ref type, ref value, ref valueSize);
var message = $"Hibernate after {value} seconds.";
Using Registry
HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Windows
CurrentVersion
explorer
ControlPanel
NameSpace
{025A5937-A6BE-4686-A844-36FE4BEC8B6D}
Then you can find value of ProvAcSettingIndex
from the following key, if the value has been changed:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Control
Power
PowerSettings
<Value of sub group GUID>
<Value of setting GUID>
DefaultPowerSchemeValues
<VALUE OF ACTIVE PLAN>
Or if the value has it’s default value, you can find it here:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Control
Power
User
PowerSchemes
<VALUE OF ACTIVE PLAN>
<Value of subgroup GUID>
<Value of setting GUID>
So you should first check for the existence of the custom value, then if it doesn’t exists, check the default value. Here is the code:
var seconds = 0;
var HKLM = Microsoft.Win32.Registry.LocalMachine;
var activePlanKeyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion" +
@"\Explorer\ControlPanel\NameSpace\" +
"{025A5937-A6BE-4686-A844-36FE4BEC8B6D}";
var activePlan = HKLM.OpenSubKey(activePlanKeyName).GetValue("PreferredPlan");
var sleepGroup = "238c9fa8-0aad-41ed-83f4-97be242c8f20";
var hibernateAfter = "9d7815a6-7ee4-497e-8888-515a05f02364";
var userCustomKeyName = $@"SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes\" +
$@"{activePlan}\{sleepGroup}\{hibernateAfter}";
var defaultKeyName = $@"SYSTEM\CurrentControlSet\Control\Power\PowerSettings\" +
$@"{sleepGroup}\{hibernateAfter}\DefaultPowerSchemeValues\{activePlan}";
var key = HKLM.OpenSubKey(userCustomKeyName, false);
if (key != null)
{
var result = key.GetValue("ACSettingIndex");
if (result != null)
seconds = (int)result;
}
else
{
key = HKLM.OpenSubKey(defaultKeyName, false);
seconds = (int)key.GetValue("ProvAcSettingIndex");
}
var message = $"Hibernate after {seconds} seconds.";
Using WMI
To use WMI solution, you first need to add reference to System.Management.dll
and add using System.Management;
then using the following code, we first find active plan GUID using Win32_PowerPlan
, then using Win32_PowerSettingDataIndex
we can get the value:
var scope = @"root\cimv2\power";
var query = "SELECT * FROM Win32_PowerPlan WHERE IsActive = True";
var searcher = new ManagementObjectSearcher(scope, query);
var activePlan = searcher.Get().Cast<ManagementObject>().First();
var activePlanId = ((string)activePlan.GetPropertyValue("InstanceId")).Split('\\')[1];
var hibernateAfter = activePlan.GetRelated("Win32_PowerSettingDataIndex").Cast<ManagementObject>()
.Where(x => (string)x.GetPropertyValue("InstanceId") ==
$@"Microsoft:PowerSettingDataIndex\{activePlanId}\AC\{{9d7815a6-7ee4-497e-8888-515a05f02364}}"
).First();
var value = (uint)hibernateAfter.GetPropertyValue("SettingIndexValue");
var message = $"Hibernate after {value} seconds.";
Very good post. This was one of the very few posts that shows how to tie power settings together through WMI. It seems that most folks are using Powercfg. I was looking for a way to remotely query power settings which WMI is great for. Here is what I came up with in PowerShell using what I learned here as a foundation:
https://www.dhb-scripting.com/Forums/posts/t44-Line-Up-Your-Windows-Power-and-Sleep-Settings-with-PowerShell-and-WMI