166 lines
6.3 KiB
C#
166 lines
6.3 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|