Friday 31 August 2007

How to run a process at a specified time on Windows Mobile 5.0

I had been banging my head against a brick wall for weeks trying to figure out how to get a process to run in an infinate loop reliably and with good performance on a mobile device. What I really wanted was a windows scheduled task, but usefully this is one of the features not available in windows mobile.

The solution I came across was the CeRunAppAtTime API. This needs a System Time object and the path to an exe. The code is below, but essentially it is a wrapper class which exposes a single static method. This method sets up a path to the program and a time to start the process at (relative to the current time), and calls the API. This class should be able to be added to any mobile solution to allow it to start a process at a specified time.

In my context, this was called as the last command in the program (after everything else had been completed) and it invoked itself so that it ran again after a specified amount of time.

Perhaps this is not an optimum solution, but it solved my problem :-)

public class Processes
{
///


/// Structure representing a system time.
/// This is used to define the time at the application
/// should next be run.
///
private struct SystemTime
{
#region Private properties

private short _year;
private short _month;
private short _dayOfWeek;
private short _day;
private short _hour;
private short _minute;
private short _second;
private short _milliseconds;

#endregion

#region Public Accessors

///


/// Represents the Year component of this SystemTime
///
public short Year
{
get { return _year; }
set { _year = value; }
}

///


/// Represents the Month component of this SystemTime
///
public short Month
{
get { return _month; }
set { _month = value; }
}

///
/// Represents the DayOfWeek component of this SystemTime
///
public short DayOfWeek
{
get { return _dayOfWeek; }
set { _dayOfWeek = value; }
}

///
/// Represents the Day component of this SystemTime
///
public short Day
{
get { return _day; }
set { _day = value; }
}

///
/// Represents the Hour component of this SystemTime
///
public short Hour
{
get { return _hour; }
set { _hour = value; }
}

///
/// Represents the Minute component of this SystemTime
///
public short Minute
{
get { return _minute; }
set { _minute = value; }
}

///
/// Represents the Second component of this SystemTime
///
public short Second
{
get { return _second; }
set { _second = value; }
}

///
/// Represents the Milliseconds component of this SystemTime
///
public short Milliseconds
{
get { return _milliseconds; }
set { _milliseconds = value; }
}

#endregion

///


///
Public constructor
///
The DateTime to populate the SystemTime object with
public
SystemTime(DateTime value)

{

_year = (Int16)value.Year;
_month = (
Int16)value.Month;
_dayOfWeek = (
Int16)value.DayOfWeek;
_day = (
Int16)value.Day;
_hour = (
Int16)value.Hour;
_minute = (
Int16)value.Minute;
_second = (
Int16)value.Second;
_milliseconds = (
Int16)value.Millisecond;

}

}

/// A reference to the API call which allows the scheduling
/// of a process.
/// The success of the invokation
[
DllImport("coredll.dll", CallingConvention = CallingConvention.Winapi)]
private
static extern bool CeRunAppAtTime(string pwszAppName, ref SystemTime lpTime);

/// Start an application at a specified time.
/// The application to start, whether to start it and the
/// number of seconds to elapse before starting it are
/// all defined in the App.Config file
public static void StartApp()
{
string ProgramPath = @"c:\myProgramPath\MyProgram.exe"; SystemTime timeToLaunch = new SystemTime(DateTime.Now.AddSeconds(30);

CeRunAppAtTime(ProgramPath, ref timeToLaunch);
}

}

Note that this code requires a reference to System.Runtime.InteropServices.

NOTE: This does not work in the standard Visual Studio emulator, but it does work on a real device.

Friday 10 August 2007

A problem has occurred with filesys.exe

So, there I was happily coding away on my Windows Mobile 5.0 Pocket PC project. I made a small change to the code, pressed F5 and suddenly BANG, it stops working. I get an error on the emulator entitled "A problem has occurred with filesys.exe", and visual studio tells me that it has lost communication with the device.

Oops I thought, VS has got it's knickers in a twist and needs to be re-started. No joy. Soft re-set the device. No Joy. Reboot my dev machine. No Joy. Now I'm becomming a little frustrated. Hard reboot the device. No Joy.

I tried all sorts of combinations of actions, but what finally worked was the following....

Delete the source code from my local machine (It's in source control still though!)
Close all programs.
Uninstall the Windows Mobile 5.0 Pocket PC SDK
Uninstall Active Sync
Restart the machine.
Install Windows Mobile 5.0 Pocket PC SDK
Install Active Sync
Restart the machine again
Get the source code back from source control
Open my solution
Run the project

And Hey presto - it's working again.

I have no idea what went wrong, and quite frankly I don't care! It works again and as long as the episode is not repeated, I'll be happy for that.

If anyone can shed any light on the problem however, i'd be interested to know why it happened, and more importantly what can be done to prevent it happening again.

Monday 6 August 2007

Welcome

Well, finally I have decided to get a blog. Watch this space for nothing in particular about things what may be interesting....