Search code examples
c#pinvokewindows-ceactivesync

WIN CE 5.0 ActiveSync Connect/Disconnect?


I'm having to back port some software from Windows Mobile 6.5 to Windows CE 5.0, the software currently detects when the unit is in the base unit (ActiveSync running).

I need to know when ActiveSync is running on the unit so that I can prepare the unit to send and receive files.

I've found an article on using PINVOKE methods such as CeRunAppAtEvent but I am clueless on how that would work.

    bool terminateDeviceEventThreads = false;
    IntPtr handleActiveSyncEndEvent;

    while (!terminateDeviceEventThreads)
        {
        handleActiveSyncEndEvent = NativeMethods.CreateEvent (IntPtr.Zero,
                                            true, false, "EventActiveSync");
        if (IntPtr.Zero != handleActiveSyncEndEvent)
            {
            if (NativeMethods.CeRunAppAtEvent ("\\\\.\\Notifications\\NamedEvents\\EventActiveSync",
                         (int) NOTIFICATION_EVENT.NOTIFICATION_EVENT_RS232_DETECTED))
                {
                NativeMethods.WaitForSingleObject (handleActiveSyncEndEvent, 0);

                //

                NativeMethods.ResetEvent (handleActiveSyncEndEvent);
                if (!NativeMethods.CeRunAppAtEvent ("\\\\.\\Notifications\\NamedEvents\\EventActiveSync",
                                 (int) NOTIFICATION_EVENT.NOTIFICATION_EVENT_NONE))
                    {
                    break;
                    }
                handleActiveSyncEndEvent = IntPtr.Zero;
                }
            }
        }

Solution

  • The code you have here is waiting on the system notification NOTIFICATION_EVENT_RS232_DETECTED. By using CeRunAppAtEvent (a bit of a misnomer, as it's not going to run an app but instead set an event) they've registered a named system event with the name "EventActiveSync" to be set when the notification occurs.

    In essence, when the device is docked, the named system event will get set.

    Your code has got some of the wait code in there, but not fully - it's calls WaitForSingleObject, but never looks at the result and then unhooks the event. I'd think it would look more like this

    event EventHandler OnConnect = delegate{};
    
    void ListenerThreadProc()
    {
        var eventName = "OnConnect";
    
        // create an event to wait on
        IntPtr @event = NativeMethods.CreateEvent (IntPtr.Zero, true, false, eventName);
    
        // register for the notification
        NativeMethods.CeRunAppAtEvent (
               string.Format("\\\\.\\Notifications\\NamedEvents\\{0}", eventName),
               (int) NOTIFICATION_EVENT.NOTIFICATION_EVENT_RS232_DETECTED);
    
        while(!m_shutdown)
        {
            // wait for the event to be set
            // use a 1s timeout so we don't prevent thread shutdown
            if(NativeMethods.WaitForSingleObject(@event, 1000) == 0)
            {
                // raise an event
                OnConnect(this, EventArgs.Empty);
            }
        }
    
        // unregister the notification
        NativeMethods.CeRunAppAtEvent (
               string.Format("\\\\.\\Notifications\\NamedEvents\\{0}", eventName),
               (int) NOTIFICATION_EVENT.NOTIFICATION_EVENT_NONE);
    
        // clean up the event handle
        NativeMethods.CloseHandle(@event);
    }
    

    Your app would create a thread that uses this proc at startup and wire up an event handler for the OnConnect event.

    FWIW, the SDF has this already done, so it would be something like this in your code:

    DeviceManagement.SerialDeviceDetected += DeviceConnected;
    ...
    void DeviceConnected()
    {
        // handle connection
    }