Wednesday, March 19, 2008

Windows Mobile: How to run a method when device wakes up/ comes back from sleep mode


Share

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();
}

21 comments:

Yohay on March 24, 2008 4:18 AM said...

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...

Debrevan on April 6, 2008 1:54 PM said...

Wow what a beautiful story. I have read your blog for a long time and have never posted a comment...It is no wonder that you often don't open up comments with all the wack jobs out in this world.

Tom said...

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

jasmine said...

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

Tom said...

Jasmine,
thanks for your resonse - I am glad you will post your fix.

Jasmine’s Mobile World » Blog Archive » Windows Mobile, C#: How to stop a thread after calling CeRunAppAtEvent / WaitForSingleObject on April 17, 2008 9:37 AM said...

[...] 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 [...]

jasmine said...

Hey Tom,
Sorry for the delay...
have a look at this:
http://jajahdevblog.com/jasmine/?p=47
let me know if worked or not...

Tom said...

Thank you very much Jasmine, it works like a charm :)

jasmine said...

Tom,
Thanks :)
Happy I could help

'ILLEGAL on April 28, 2008 6:13 PM said...

None...

None...

Taridzo said...

Thanks a million, just what I needed, I only had to tweak it a little bit because I didnt need to close() my application.

Lu Fang said...

I have been search on internet for ages...this is the only one that works really well! thank hips!!!

Waydaynok on June 5, 2008 4:36 PM said...

Nice site. I think you should add little more description in your post, anyway I liked it. Thanks

Shiva said...

How do I implement General.NoParamsFunctionHandler?

jasmine said...

public delegate void NoParamsFunctionHandler();
:)

Shiva said...

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!");
}

Steve said...

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

Steve said...

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!

Vince Delmonte on April 15, 2009 5:11 AM said...

I follow your blog for a long time and should tell that your articles always prove to be of a high value and quality for readers.

Jasmine Aharon on November 5, 2009 1:05 AM said...
This comment has been removed by the author.
Jasmine on November 5, 2009 1:06 AM said...

The fix is here:
http://www.blondmobile.com/2008/04/windows-mobile-c-how-to-stop-thread.html

Post a Comment

 

Blogroll

Site Info

Text