Windows Mobile: How to run a method when device wakes up/ comes back from sleep mode
Thursday, March 20th, 2008Its very surprising that there is no wakeup event or member in the managed SystemState class that indicates that the device has returned from sleep mode.
Fortunately, we can use the CeRunAppAtEvent function from coredll.
public static extern bool CeRunAppAtEvent(string AppName, int WhichEvent);
Starting an application when the device wakes up, is very straight forward, and all you need is to pass the path of the application to run (and also remember to remove it…)
Running a method is a bit more complicated; instead of the application path you would write
"\\\\.\\Notifications\\NamedEvents\\eventName"
Where the eventName is a name of a native event. here is the code you will need to start a wakeup event, catch it and run your method
private const int NOTIFICATION_EVENT_WAKEUP = 11; private const UInt32 INFINITE = 0xFFFFFFFF; [DllImport("coredll.dll", SetLastError = true)] public static extern bool CeRunAppAtEvent(string AppName, int WhichEvent); [DllImport("coredll.dll",SetLastError = true)] private static extern int WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); [DllImport("coredll.dll", SetLastError = true)] private static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string spName); private static General.NoParamsFunctionHandler _eventToRunOnWakeup; public static General.NoParamsFunctionHandler EventToRunOnWakeup { set { if (_eventToRunOnWakeup == null)// so we only run one thread StartOnWakeUpService(); _eventToRunOnWakeup = value; } } private static void StartOnWakeUpService() { try { CeRunAppAtEvent( "\\\\.\\Notifications\\NamedEvents\\NativeDeviceWakeUpEvent", NOTIFICATION_EVENT_WAKEUP); _wakeupServiceThread = new Thread(new ThreadStart(WakeupProc)); _wakeupServiceThread.Start(); } catch { } } private static void WakeupProc() { IntPtr hEvent = CreateEvent(IntPtr.Zero, false, false, "NativeDeviceWakeUpEvent"); while (!_close) { WaitForSingleObject(hEvent, INFINITE); if (_eventToRunOnWakeup != null) _eventToRunOnWakeup(); } }
since this thread will be running in the background, we want to make sure it will stop when we are done. hence the below method
public static void Close() { _close = true; if(_wakeupServiceThread != null) _wakeupServiceThread.Abort(); }