Blond Mobile


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,

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

  1. Yohay Says:

    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…

  2. Tom Says:

    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

  3. jasmine Says:

    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

  4. Tom Says:

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

  5. Jasmine’s Mobile World » Blog Archive » Windows Mobile, C#: How to stop a thread after calling CeRunAppAtEvent / WaitForSingleObject Says:

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

  6. jasmine Says:

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

  7. Tom Says:

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

  8. jasmine Says:

    Tom,
    Thanks :)
    Happy I could help

  9. Taridzo Says:

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

  10. Lu Fang Says:

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

  11. Shiva Says:

    How do I implement General.NoParamsFunctionHandler?

  12. jasmine Says:

    public delegate void NoParamsFunctionHandler();
    :)

  13. Shiva Says:

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

  14. Steve Says:

    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

  15. Steve Says:

    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!

Leave a Reply

Jajah is the VoIP player that brought you web-activated telephony.