Flow-Launcher/Flow.Launcher · warning · Win32Exception
Error registering for power notifications: {Marshal.GetLastW
Error message
Error registering for power notifications: {Marshal.GetLastWin32Error()} What it means
Thrown as Win32Exception when PowerRegisterSuspendResumeNotification returns anything other than ERROR_SUCCESS, leaving _handle as HPOWERNOTIFY.Null. The message includes Marshal.GetLastWin32Error() to surface the OS-level reason. This API registers a callback to receive sleep/resume notifications and normally only fails under specific OS/security conditions.
Source
Thrown at Flow.Launcher.Infrastructure/Win32Helper.cs:978
_func = func;
_callback = new PDEVICE_NOTIFY_CALLBACK_ROUTINE(DeviceNotifyCallback);
_recipient = new DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS()
{
Callback = _callback,
Context = null
};
_recipientHandle = new StructSafeHandle<DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS>(_recipient);
_handle = PInvoke.PowerRegisterSuspendResumeNotification(
REGISTER_NOTIFICATION_FLAGS.DEVICE_NOTIFY_CALLBACK,
_recipientHandle,
out var handle) == WIN32_ERROR.ERROR_SUCCESS ?
new HPOWERNOTIFY(new IntPtr(handle)) :
HPOWERNOTIFY.Null;
if (_handle.IsNull)
{
throw new Win32Exception("Error registering for power notifications: " + Marshal.GetLastWin32Error());
}
}
/// <summary>
/// Unregisters the sleep mode listener.
/// </summary>
public static void UnregisterSleepModeListener()
{
if (!_handle.IsNull)
{
PInvoke.PowerUnregisterSuspendResumeNotification(_handle);
_handle = HPOWERNOTIFY.Null;
_func = null;
_callback = null;
_recipientHandle = null;
}
}
View on GitHub (pinned to 7fc63b07bb)
Solutions
- Decode Marshal.GetLastWin32Error() from the message (e.g. 87 ERROR_INVALID_PARAMETER, 5 ERROR_ACCESS_DENIED) to classify.
- Verify the DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS and the callback delegate are kept alive (not GC'd) for the registration's lifetime — the _callback field is allocated for this reason; ensure it isn't nulled.
- Confirm the OS supports PowerRegisterSuspendResumeNotification (Windows Vista+, desktop session).
- Catch Win32Exception at the caller and degrade to a polling/lesser mechanism for power-state awareness if registration is unavailable.
- Re-check the P/Invoke signature against the current Windows SDK if the HRESULT is unexpected.
Example fix
// before
if (_handle.IsNull)
throw new Win32Exception("Error registering for power notifications: " + Marshal.GetLastWin32Error());
// after — include the HRESULT and degrade gracefully
if (_handle.IsNull)
{
var err = Marshal.GetLastWin32Error();
Log.Exception(nameof(Win32Helper), $"PowerRegisterSuspendResumeNotification failed (Win32 error {err}); power-state tracking disabled", null);
// do not throw — continue without sleep/resume notifications
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try { Win32Helper.RegisterSleepModeListener(callback); }
catch (Win32Exception ex) when (ex.Message.Contains("power notifications"))
{ Log.Warn(...); // continue without sleep/resume notifications } Prevention
- Keep the callback delegate and the StructSafeHandle alive for the registration's lifetime to avoid GC invalidating the pointer.
- Verify the P/Invoke signature matches the current Windows SDK / CsWin32 output.
- Catch Win32Exception at the caller and degrade gracefully — power tracking is non-critical.
- Confirm the OS edition supports power-notification registration before relying on it.
When it happens
Trigger: The OS rejected the callback registration due to an invalid recipient structure, a marshalling failure of the DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS, or (rarely) insufficient privilege; running on a Windows edition/configuration that restricts power notifications; the StructSafeHandle holding _recipient was disposed or invalid at call time; a P/Invoke signature mismatch producing a non-SUCCESS return.
Common situations: An older/locked-down Windows build (kiosk, embedded) disabling power notification registration; a bug in the StructSafeHandle marshalling causing the callback pointer to be invalid; running under a heavily restricted service account; a CsWin32 generator mismatch producing wrong binding for PowerRegisterSuspendResumeNotification.
Related errors
- Failed to get IShellItemImageFactory
- Failed to get thumbnail
- Invalid corner type
- Failed to parse folder path
- Failed to parse file path
AI-assisted analysis of Flow-Launcher/Flow.Launcher@7fc63b07bb (2026-08-13).
Data as JSON: /api/errors/265b89591c2e72a6.
Report an issue: GitHub.