Windows Mobile: How to run a method when device wakes up/ comes back from sleep mode
Its 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(); }
Tags: CeRunAppAtEvent, Coredll, Sleep Mode, SystemState, Windows Mobile
March 24th, 2008 at 11:18 am
It truly is surprising that such a basic call requires importing external DLLs. I would have expected to see this as an integral part of the object model.
Well, hopefully performance is swift…
April 16th, 2008 at 12:07 am
Hi there,
thank you very much for your article - it works fine except that I can not stop my application. After I call _wakeupServiceThread.Abort(); the Thread waits at WaitForSingleObject(hEvent, INFINITE);
Is there a way to force the thread to quit? I added wakeupServiceThread.IsBaground - but this does not help either.
Thank you,
Tom
April 16th, 2008 at 9:39 am
Hey Tom,
Thanks!
Im happy my post helped you.
You are right, the application cannot close. I fixed that issue in my code and didn’t post the solution. I will post the fix tonight
April 16th, 2008 at 7:50 pm
Jasmine,
thanks for your resonse - I am glad you will post your fix.
April 17th, 2008 at 4:37 pm
[...] a previous post, I wrote about how to run a method when the device wakes up, or comes back from sleep mode. In that post I wrote about calling the CeRunAppAtEvent native function, which signals a [...]
April 17th, 2008 at 4:39 pm
Hey Tom,
Sorry for the delay…
have a look at this:
https://jajahdevblog.com/jasmine/?p=47
let me know if worked or not…
April 17th, 2008 at 7:28 pm
Thank you very much Jasmine, it works like a charm
April 20th, 2008 at 12:15 am
Tom,
Thanks
Happy I could help
May 6th, 2008 at 10:27 am
Thanks a million, just what I needed, I only had to tweak it a little bit because I didnt need to close() my application.
May 12th, 2008 at 11:39 pm
I have been search on internet for ages…this is the only one that works really well! thank hips!!!
July 2nd, 2008 at 5:50 am
How do I implement General.NoParamsFunctionHandler?
July 2nd, 2008 at 10:01 am
public delegate void NoParamsFunctionHandler();
July 3rd, 2008 at 2:27 am
Jasmine,
Thanks. Works but for some reason I get the MessageBox that I am showing in the EventToRunOnWakeup method TWO times and ONCE when I am closing the sample Form. Am I doing something stupid(see pasted code below). If you send me a mail I can send the whole code I have. Thanks for your help.
WakeUpService.EventToRunOnWakeup = delegate() { HelloWorld(); };
void HelloWorld()
{
MessageBox.Show(”Hello World!”);
}
August 21st, 2008 at 5:45 pm
Jasmine,
Thanks for the code. I have it working but I get event firing twice also.
I’m not too bothered about that though as I can handle that in my code.
I have a problem where the event fires as soon as I turn the device back on but if I show a messagebox it takes about 15 seconds to display after turn on. I Log the time the event fires and that is OK, pretty much instantly after the power on, but showing the message takes 15 seconds.
Do you have any idea why this happens!?
Thanks
Steve
August 21st, 2008 at 6:11 pm
Forget about my last post, it was taking 15 seconds to write the Log Time into my log file for whatever reason but displaying a message box is instant.
Sorry!