PowerSettingRegisterNotification (powrprof)
Last changed: Chipsaru-92.244.120.109

.
Summary
Registers to receive notification when a power setting changes.

C# Signature:

[DllImport("powrprof.dll", SetLastError=true)]
static extern int PowerSettingRegisterNotification(ref Guid settingGuid, uint flags, ref DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient, ref IntPtr registrationHandle);

VB Signature:

Declare Function PowerSettingRegisterNotification Lib "powrprof.dll" (TODO) As TODO

User-Defined Types:

    /// <summary>
    /// OS callback delegate definition
    /// </summary>
    /// <param name="context">The context for the callback</param>
    /// <param name="type">The type of the callback...for power notifcation it's a PBT_ message</param>
    /// <param name="setting">A structure related to the notification, depends on type parameter</param>
    /// <returns></returns>
    delegate int DeviceNotifyCallbackRoutine(IntPtr context, int type, IntPtr setting);

    /// <summary>
    /// A callback definition
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    struct DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS
    {
        public DeviceNotifyCallbackRoutine Callback;
        public IntPtr Context;
    }

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

Remember to unsubscribe with PowerSettingUnregisterNotification

Tips & Tricks:

https://docs.microsoft.com/en-us/windows/desktop/power/power-setting-guids

Sample Code:

Sample that monitors display state:

    private readonly DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS _recipient;
    private IntPtr _handle;

    const int DEVICE_NOTIFY_CALLBACK = 0x2;
    const int PBT_POWERSETTINGCHANGE = 0x8013;

    // 6fe69556-704a-47a0-8f24-c28d936fda47
    static Guid GUID_CONSOLE_DISPLAY_STATE = new Guid(0x6fe69556, 0x704a, 0x47a0, 0x8f, 0x24, 0xc2, 0x8d, 0x93, 0x6f, 0xda, 0x47);

    delegate int DeviceNotifyCallbackRoutine(IntPtr context, int type, IntPtr setting);

    [StructLayout(LayoutKind.Sequential)]
    struct DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS
    {
        public DeviceNotifyCallbackRoutine Callback;
        public IntPtr Context;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    struct POWERBROADCAST_SETTING
    {
        public Guid PowerSetting;
        public uint DataLength;
        public byte Data;
    }

    [DllImport("Powrprof.dll", SetLastError = true)]
    private static extern int PowerSettingRegisterNotification(ref Guid settingGuid, uint flags, ref DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient, ref IntPtr registrationHandle);

    [DllImport("Powrprof.dll", SetLastError = true)]
    private static extern int PowerSettingUnregisterNotification(IntPtr registrationHandle);

    public void Register()
    {
         _recipient = new DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS
         {
         Callback = HandlerCallback,
         Context = IntPtr.Zero
         };

        var registrationHandle = new IntPtr();
        var result = PowerSettingRegisterNotification(ref GUID_CONSOLE_DISPLAY_STATE, DEVICE_NOTIFY_CALLBACK, ref _recipient, ref registrationHandle);
        if (result == 0)
        {
        _handle = registrationHandle;
        }
        else
        {
        Console.WriteLine("Error: {0}", result);
        }
    }

    public void Unregister()
    {
        if (_handle != IntPtr.Zero)
        {
        PowerSettingUnregisterNotification(_handle);
        _handle = IntPtr.Zero;
        }
    }

    private int HandlerCallback(IntPtr context, int eventType, IntPtr setting)
    {
        if (eventType == PBT_POWERSETTINGCHANGE
        && Marshal.PtrToStructure(setting, typeof(POWERBROADCAST_SETTING)) is POWERBROADCAST_SETTING powersetting
        && powersetting.PowerSetting == GUID_CONSOLE_DISPLAY_STATE)
        {
        switch (powersetting.Data)
        {
            case 0x0: // 0x0 - The display is off.
            Console.WriteLine("Display OFF");
            break;
            case 0x1: // 0x1 - The display is on.
            Console.WriteLine("Display ON");
            break;
            case 0x2: // 0x2 - The display is dimmed.
            Console.WriteLine("Display DIMMED");
            break;
        }
        }
        return 0;
    }

Documentation