Skip to content

Instantly share code, notes, and snippets.

@eric-b
Last active December 4, 2016 19:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eric-b/c73b4869fb58a5b5d750a42ddf3de951 to your computer and use it in GitHub Desktop.
Save eric-b/c73b4869fb58a5b5d750a42ddf3de951 to your computer and use it in GitHub Desktop.
using System;
using System.Management;
public class Program
{
public static void Main(string[] args)
{
using (var watcher = new Win32PowerManagementEventWatcher())
{
watcher.Start();
watcher.OnSuspend += OnSystemEvent;
watcher.OnResume += OnSystemEvent;
Console.ReadKey();
}
}
private void OnSystemEvent(object sender, Win32PowerManagementEventWatcherEventArgs e)
{
Console.WriteLine("Event: {0}", e.EventType);
}
}
public enum PowerModeEventType : ushort
{
EnteringSuspend = 4,
ResumeFromSuspend = 7,
PowerStatusChanged = 10,
OemEvent = 11,
ResumeAutomatic = 18
}
public delegate void Win32PowerManagementEventWatcherEventHandler(object sender, Win32PowerManagementEventWatcherEventArgs e);
public sealed class Win32PowerManagementEventWatcherEventArgs : EventArgs
{
private readonly DateTime _createdAtUtc;
private readonly PowerModeEventType _eventType;
public Win32PowerManagementEventWatcherEventArgs(PowerModeEventType eventType, DateTime createdAtUtc)
{
_eventType = eventType;
_createdAtUtc = createdAtUtc;
}
public DateTime CreatedAtUtc
{
get
{
return _createdAtUtc;
}
}
public PowerModeEventType EventType
{
get
{
return _eventType;
}
}
}
public sealed class Win32PowerManagementEventWatcher : IDisposable
{
private static readonly TimeSpan MinDelayBetween2Resumes = TimeSpan.FromMinutes(1);
private readonly ManagementEventWatcher _watcher;
private bool _started;
private DateTime _lastResume;
public event Win32PowerManagementEventWatcherEventHandler OnSuspend;
public event Win32PowerManagementEventWatcherEventHandler OnResume;
public event Win32PowerManagementEventWatcherEventHandler OnAnyEvent;
public Win32PowerManagementEventWatcher()
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += OnSystemEventsPowerModeChanged;
}
public void Start()
{
if (_started)
return;
_watcher.Start();
_started = true;
}
public void Stop()
{
if (!_started)
return;
_started = false;
_watcher.Stop();
}
private void OnSystemEventsPowerModeChanged(object sender, EventArrivedEventArgs e)
{
// RECOMMENDED: wrapped in a try catch with your logger...
var eventType = (PowerModeEventType)(ushort)e.NewEvent.Properties["EventType"].Value;
var createdAt = (long)(ulong)e.NewEvent.Properties["TIME_CREATED"].Value;
var date = DateTime.FromFileTimeUtc(createdAt);
var arg = new Win32PowerManagementEventWatcherEventArgs(eventType, date);
OnAnyEvent?.Invoke(this, arg);
switch (eventType)
{
case PowerModeEventType.EnteringSuspend:
OnSuspend?.Invoke(this, arg);
break;
case PowerModeEventType.ResumeFromSuspend:
case PowerModeEventType.ResumeAutomatic:
if (date.Subtract(_lastResume) > MinDelayBetween2Resumes)
{
_lastResume = date;
OnResume?.Invoke(this, arg);
}
break;
case PowerModeEventType.PowerStatusChanged:
case PowerModeEventType.OemEvent:
default:
break;
}
}
public void Dispose()
{
if (_started)
Stop();
_watcher.EventArrived -= OnSystemEventsPowerModeChanged;
_watcher.Dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment