Connections CE and Active Sync

M

Maxus

Hi People,

I have written my first CE application that uses SQL CE to store its
data when the user chooses syncronise the data is shifted from the unit
to the main server and removed off the unit. All of this works
brilliantly (i actually thought that would be the hard bit).

Now I need a way to trigger the sync'ing automatically when the unit is
connected or in a cradle. I have read through a huge amount of forums
and basically driven my self nuts. Here are the solutions I have tried
:

1. CeRunAppAtEvent method - This works except it has to run a seperate
application and some how comunicate back to the orginal application not
a good solution found it unstable. It also fires the event when the
unit is restarted causing applications to open up over and over.

2. I tried OpenNETCF: using the code below and linked to the event but
there seem to be a bug where it never actually fires the event. I think
beacuse the unit has a wireless and active sync connecton this seem to
only moniter the wireless which we dont use (but might in future). I
cant figure out how to set the CE unit to moniter the active sync
connection.

AdapterStatusMonitor ASM = AdapterStatusMonitor.NDISMonitor;
ASM.AdapterNotification += new EventHandler(ASM_AdapterNotification);
ASM.StartStatusMonitoring();

3. NotifyAddrChange : This a non managed function I was hoping It
could just detect the IP change and fire an event to sync from that.
but I have no idea how to DLL import it into managed code

4. Another options is to make call to web sites or a server and wait to
see if it times out Or check the IP on the interfaces. This would need
to be put in a Loop in a seperate thread and fire events back to cause
it to sync when things change. This is also one i have no idea how to
do :(

Does anyone know how I can do this?

Thanks in advance!
M
 
M

Miguel

The way that I went was by using CeRunAppAtEvent. If you like closely
to the documentation, you would see that CeRunAppAtEvent can also be
used to to trigger at an event. In order to do this, you will have to
invoke CreateEvent and give it a name xxx. Then when you invoke
CeRunAppAtEvent, the first parameter will be of the form
"\\\\.\\Notifications\\NamedEvents\\xxx".
And through the use of a thread which waits for the event to trigger (
invoking WaitForSingleObject) you can get what you want :)

Kind regards

More Info:
http://msdn.microsoft.com/library/d.../wceshellui5/html/wce50lrfCeRunAppAtEvent.asp
(it also works for PPC2003)
 
M

Maxus

Hi Miguel,

Your a legend, Thanks! I don't have any non-managed code skills so i
just took a ruff guess does this look right?


[DllImport("coredll.dll", EntryPoint="CeRunAppAtEvent",
SetLastError=true)]
private static extern int CeRunAppAtEvent(string pwszAppName,
NOTIFICATION_EVENT lWhichEvent);

/// <summary>
///
/// </summary>
public enum NOTIFICATION_EVENT : int
{
/// <summary>
/// NOTIFICATION_EVENT_NONE
/// </summary>
NOTIFICATION_EVENT_NONE = 0,

/// <summary>
/// NOTIFICATION_EVENT_TIME_CHANGE
/// </summary>
NOTIFICATION_EVENT_TIME_CHANGE = 1,

/// <summary>
/// NOTIFICATION_EVENT_SYNC_END
/// </summary>
NOTIFICATION_EVENT_SYNC_END = 2,

/// <summary>
/// NOTIFICATION_EVENT_ON_AC_POWER
/// </summary>
NOTIFICATION_EVENT_ON_AC_POWER = 3,

/// <summary>
/// NOTIFICATION_EVENT_OFF_AC_POWER
/// </summary>
NOTIFICATION_EVENT_OFF_AC_POWER = 4,

/// <summary>
/// NOTIFICATION_EVENT_NET_CONNECT
/// </summary>
NOTIFICATION_EVENT_NET_CONNECT = 5,

/// <summary>
/// NOTIFICATION_EVENT_NET_DISCONNECT
/// </summary>
NOTIFICATION_EVENT_NET_DISCONNECT = 6,

/// <summary>
/// NOTIFICATION_EVENT_DEVICE_CHANGE
/// </summary>
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,

/// <summary>
/// NOTIFICATION_EVENT_IR_DISCOVERED
/// </summary>
NOTIFICATION_EVENT_IR_DISCOVERED = 8,

/// <summary>
/// NOTIFICATION_EVENT_RS232_DETECTED
/// </summary>
NOTIFICATION_EVENT_RS232_DETECTED = 9,

/// <summary>
/// NOTIFICATION_EVENT_RESTORE_END
/// </summary>
NOTIFICATION_EVENT_RESTORE_END = 10,

/// <summary>
/// NOTIFICATION_EVENT_WAKEUP
/// </summary>
NOTIFICATION_EVENT_WAKEUP = 11,

/// <summary>
/// NOTIFICATION_EVENT_TZ_CHANGE
/// </summary>
NOTIFICATION_EVENT_TZ_CHANGE = 12,

/// <summary>
/// NOTIFICATION_EVENT_MACHINE_NAME_CHANGE
/// </summary>
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
}


private void WaitForNotificationEvent(NOTIFICATION_EVENT
notificationEvent)
{
CeRunAppAtEvent("\\\\.\\Notifications\\NamedEvents\\CM_CradleNotification",
notificationEvent);
}

private void CM_CradleNotification(object sender, EventArgs e)
{
MessageBox.Show("Connected");
}

It missing something and if i knew C++ I'm sure I could spot it ;)

Any ideas what im missing?
Thanks
M
 
M

Miguel

You also have to create the CM_CradleNotification event with the use of
invoking CreateEvent
In a different thread you will have something like this
CeRunAppAtEvent(.....)
IntPtr handle = CreateEvent(.....) // P/Invoke, look at API
While(True){
WaitForSingleObject(handle,&hFFFFFFFF); // Wait forever until
the event is triggerend
// When you come at this point the event has been triggered
.....
}

Regards
 
M

Miguel

To give you the entire picture:

private void ListenToActiveSync(){ // Thread
CeRunAppAtEvent("\\\\.\\Notifications\\NamedEvents\\CradleEvent" +
"\0" ,NOTIFICATION_EVENT_RS232_DETECTED);
IntrPtr handle = CreateEvent(null,0,0,"CradleEvent" + "\0");
While(true){
WaitForSingleObject(handle,0xFFFFFFFF);
// Device is cradled at this point
// ....
}
}
[DllImport("coredll.dll",
EntryPoint="CeRunAppAtEvent",SetLastError=true)]
private static extern int CeRunAppAtEvent(string
pwszAppName,NOTIFICATION_EVENT whichEvent);

[DllImport("coredll.dll", EntryPoint="CreateEvent",SetLastError=true)]
private static extern IntPtr CreateEvent(Intptr security,int
manualreset,int initialstate,string name);

[DllImport("coredll.dll",
EntryPoint="WaitForSingleObject",SetLastError=true)]
private static extern int WaitForSingleObject(IntPtr handle,int
millisec);
 
M

Maxus

Hi Miguel,

Thanks a heap for you help it works like a charm!

Here is the final code for anyone seeking to do this:

private Thread CradleMoniterThread;

private void frmLogin_Load(object sender, System.EventArgs e)
{

CradleMoniterThread = new Thread(new
ThreadStart(this.WaitForNotificationEvent));
CradleMoniterThread.Priority = ThreadPriority.Normal;
CradleMoniterThread.Start();

}

[DllImport("coredll.dll", EntryPoint="CeRunAppAtEvent",
SetLastError=true)]
private static extern int CeRunAppAtEvent(string pwszAppName,
NOTIFICATION_EVENT lWhichEvent);

[DllImport("coredll.dll", EntryPoint="CreateEvent",SetLastError=true)]
private static extern IntPtr CreateEvent(IntPtr security, int
manualreset, int initialstate, string name);

[DllImport("coredll.dll",
EntryPoint="WaitForSingleObject",SetLastError=true)]
private static extern int WaitForSingleObject(IntPtr handle, uint
millisec);

#region NOTIFICATION_EVENT ...
/// <summary>
/// NOTIFICATION_EVENT
/// </summary>
public enum NOTIFICATION_EVENT : int
{
/// <summary>
/// NOTIFICATION_EVENT_NONE
/// </summary>
NOTIFICATION_EVENT_NONE = 0,

/// <summary>
/// NOTIFICATION_EVENT_TIME_CHANGE
/// </summary>
NOTIFICATION_EVENT_TIME_CHANGE = 1,

/// <summary>
/// NOTIFICATION_EVENT_SYNC_END
/// </summary>
NOTIFICATION_EVENT_SYNC_END = 2,

/// <summary>
/// NOTIFICATION_EVENT_ON_AC_POWER
/// </summary>
NOTIFICATION_EVENT_ON_AC_POWER = 3,

/// <summary>
/// NOTIFICATION_EVENT_OFF_AC_POWER
/// </summary>
NOTIFICATION_EVENT_OFF_AC_POWER = 4,

/// <summary>
/// NOTIFICATION_EVENT_NET_CONNECT
/// </summary>
NOTIFICATION_EVENT_NET_CONNECT = 5,

/// <summary>
/// NOTIFICATION_EVENT_NET_DISCONNECT
/// </summary>
NOTIFICATION_EVENT_NET_DISCONNECT = 6,

/// <summary>
/// NOTIFICATION_EVENT_DEVICE_CHANGE
/// </summary>
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,

/// <summary>
/// NOTIFICATION_EVENT_IR_DISCOVERED
/// </summary>
NOTIFICATION_EVENT_IR_DISCOVERED = 8,

/// <summary>
/// NOTIFICATION_EVENT_RS232_DETECTED
/// </summary>
NOTIFICATION_EVENT_RS232_DETECTED = 9,

/// <summary>
/// NOTIFICATION_EVENT_RESTORE_END
/// </summary>
NOTIFICATION_EVENT_RESTORE_END = 10,

/// <summary>
/// NOTIFICATION_EVENT_WAKEUP
/// </summary>
NOTIFICATION_EVENT_WAKEUP = 11,

/// <summary>
/// NOTIFICATION_EVENT_TZ_CHANGE
/// </summary>
NOTIFICATION_EVENT_TZ_CHANGE = 12,

/// <summary>
/// NOTIFICATION_EVENT_MACHINE_NAME_CHANGE
/// </summary>
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
}
#endregion

private void WaitForNotificationEvent()
{
CeRunAppAtEvent("\\\\.\\Notifications\\NamedEvents\\CradleEvent\0"
,NOTIFICATION_EVENT.NOTIFICATION_EVENT_RS232_DETECTED);

IntPtr handle = CreateEvent(IntPtr.Zero,0,0,"CradleEvent\0");
while(true)
{
WaitForSingleObject(handle,0xFFFFFFFF);
MessageBox.Show("Connected");
}
}

Thanks again for helping out Miguel!
-A
 
M

Maxus

Hi People,

The code appove seems to fire the event twice. Anyone know how to stop
it?

Thanks
A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top