Friday, September 17, 2010

Windows CE: ceRunAppAtTime -- Wake up device

 Recently, I have been working on a mobile for windows mobile 6.5. One of the requirements of the mobile application was to wake up the device at periodic intervals and do its job.


The default behavior of a mobile device is to suspend all non core/essential jobs running on the device, if the device is in sleep/standby mode. So, this presented a challenge. My app would run, as long as the phone was active or if the power options were changed to allow the device to do its job, when it was in sleep/inactive mode.


Luckily, for all of us, Microsoft provides a nice function called "ceRunAppAtTime". This function will force the device to run a specified application at the specified time regardless of the device's status, if it was active or in sleep/standby mode. However, the function only runs the application one time and not on a scheduled timer, which is what the requirements asked for.


You can make your program call itself after it has performed its job by using the above function. Essentially, the program is first kicked off/started in phone active mode, one of the first methods to call would be ceRunAppAtTime, ensuring that the program will call itself at the specified time.


Here is some sample code to make it happen.



namespace WakeUpDevice
{
    static class Program
    {
        ///
        /// The main entry point for the application.
        ///
        ///
        [DllImport("coredll.dll", EntryPoint = "CeRunAppAtTime", SetLastError=true)]
        public static extern bool ceRunAppAtTime(string appname, ref SYSTEMTIME lpTime);

      /*this structure is required for SYSTEMTIME*/
       public struct SYSTEMTIME
        {          
            public UInt16 wYear;
            public UInt16 wMonth;
            public UInt16 wDayOfWeek;
            public UInt16 wDay;
            public UInt16 wHour;
            public UInt16 wMinute;
            public UInt16 wSecond;
            public UInt16 wMilliseconds;
        }

        [MTAThread]
        static void Main()
        {

            string FullappName = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
            
            DateTime startTime = DateTime.Now + new TimeSpan(0, 3, 0);          

            SYSTEMTIME systemStartTime = new SYSTEMTIME();    
            systemStartTime.wDay = (ushort)startTime.Day;
            systemStartTime.wDayOfWeek = (ushort)startTime.DayOfWeek;
            systemStartTime.wHour = (ushort) startTime.Hour;
            systemStartTime.wMilliseconds = (ushort)startTime.Millisecond;
            systemStartTime.wMinute = (ushort)startTime.Minute;
            systemStartTime.wMonth = (ushort)startTime.Month;
            systemStartTime.wSecond = (ushort)startTime.Second;
            systemStartTime.wYear = (ushort)startTime.Year;

            try
            {
                bool res =  ceRunAppAtTime(FullAppName);    
               MessageBox.Show(res.ToString());
             }
            catch (Exception ex)
            {
                /*log exception*/
            }

            Application.Run(new Form1());
        }
    }
}

Have fun folks, the above function saved me.
Feel free to post a comment

No comments: