Files
DP44/Common/DTS.Common.Utilities/PowerManagement.cs

166 lines
6.3 KiB
C#
Raw Normal View History

2026-04-17 14:55:32 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.InteropServices;
using DTS.Common.Utilities.Logging;
namespace DTS.Common.Utilities
{
public class PowerManagement
{
[DllImport("powrprof.dll")]
static extern uint PowerGetActiveScheme(
IntPtr UserRootPowerKey,
ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
ref Guid PowerSettingGuid,
ref int Type,
ref IntPtr Buffer,
ref uint BufferSize
);
[DllImport("powrprof.dll", CharSet = CharSet.Unicode)]
static extern uint PowerReadFriendlyName(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
IntPtr PowerSettingGuid,
StringBuilder Buffer,
ref uint BufferSize
);
[DllImport("kernel32.dll")]
static extern IntPtr LocalFree(
IntPtr hMem
);
[DllImport("powrprof.dll")]
static extern uint PowerEnumerate(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
ref Guid SubGroupOfPowerSetting,
uint AccessFlags,
uint Index,
ref Guid Buffer,
ref uint BufferSize);
private const uint ERROR_MORE_DATA = 234;
private static Guid HIGH_PERFORMANCE_GUID = new Guid("8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c");
private static Guid MAX_PERFORMANCE_GUID = new Guid("01360e7e-525f-4625-ab94-f283dcfbd515");
//private static Guid GUID_PROCESSOR_SETTINGS_SUBGROUP = new Guid("GUID_PROCESSOR_SETTINGS_SUBGROUP");
//private static Guid GUID_POWERSCHEME_PERSONALITY = new Guid(0x245D8541, 0x3943, 0x4422, 0xB0, 0x25, 0x13, 0xA7, 0x84, 0xF6, 0x79, 0xB7);
private static Guid GUID_PROCESSOR_SETTINGS_SUBGROUP = new Guid("54533251-82be-4824-96c1-47b60b740d00");
private const uint ACCESS_INDIVIDUAL_SETTING = 18;
public static bool IsInHighPowerMode()
{
var activeGuidPtr = IntPtr.Zero;
try
{
uint res = 0;
//8663 don't do power warning if performance/max performance power modes don't exist
//enumerate all the schemes and look for either the high power guid or name, or max
//we could use this to determine the active one scheme, but for now we just want to log and
//not continue on if we don't find high performance/max performance.
var bContainsMaxOrHighPerformance = false;
var p = new System.Diagnostics.Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized,
FileName = "powercfg",
Arguments = "/list"
}
};
p.Start();
var output = p.StandardOutput.ReadToEnd();
//APILogger.Log("Active Power Schemes", output);
p.WaitForExit();
if (output.Contains(HIGH_PERFORMANCE_GUID.ToString()) || (output.Contains(MAX_PERFORMANCE_GUID.ToString()))
|| output.Contains("High performance") || output.Contains("Max performance")
)
{
bContainsMaxOrHighPerformance = true;
}
//8663 don't do power warning if performance/max performance power modes don't exist
if (!bContainsMaxOrHighPerformance)
{
return true;
}
res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);
if (res != 0)
throw new Win32Exception();
var g = (Guid)System.Runtime.InteropServices.Marshal.PtrToStructure(activeGuidPtr, typeof(Guid));
if (g == HIGH_PERFORMANCE_GUID || g == MAX_PERFORMANCE_GUID)
{
return true;
}
//Get Friendly Name
uint buffSize = 0;
var buffer = new StringBuilder();
var subGroupGuid = Guid.Empty;
var powerSettingGuid = Guid.Empty;
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);
if (res == ERROR_MORE_DATA)
{
buffer.Capacity = (int)buffSize;
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);
}
var name = buffer.ToString();
name = name.ToLower();
if (name.Contains("maximum performance") || name.Contains("high performance"))
{
return true;
}
else
{
APILogger.Log(string.Format("{0}\nProfile name:", APILogger.GetCurrentMethod()), name, "GUID:", g.ToString());
APILogger.Log("Active Power Schemes", output);
return false;
}
}
catch (System.Exception ex)
{
APILogger.Log(ex);
}
finally
{
if (activeGuidPtr != IntPtr.Zero)
{
var res = LocalFree(activeGuidPtr);
if (res != IntPtr.Zero)
throw new Win32Exception();
}
}
//default to okay, so if there's an error, or if we can't read, just continue on
return true;
}
}
}