Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Handling connection notification between a desktop machine and Windows CE based devices

0.00/5 (No votes)
14 Jan 2009 1  
This article describes how to get notification when a Windows CE based device is connected or disconnected from a desktop machine.

Introduction

There are two ways that a desktop application can get notification when a Windows CE-based device gets connected with the desktop application.

  1. Registry based notification

    Registry based notification has two predefined events, AutoStartOnConnect and AutoStartOnDisconnect, each of which has its own Registry key. We can register the command lines associated with the Registry key. Whenever the device gets connected with the desktop machine, the AutoStartOnConnect event will be triggered and all the command lines registered under this will be executed. Similarly, whenever a device gets disconnected from the desktop machine, the AutoStartOnDisconnect event will be triggered and all the command lines under the AutoStartOnDisconnect key will be executed.

    For more details, refer to this MSDN link: Registry based notification.

  2. COM based notification

    It includes two interfaces, IDccMan provided by Rapi.dll, and IDccManSink implemented by the application which needs the notification. These interfaces handle connection and disconnection notification.

    For more details, refer to the following link: COM based notification.

The basic difference between these two methods is that when Registry based notification causes a program to run, we cannot get notifications in the application, whereas in COM based notification, you have control on the Connection Manager, registering and deregistering for connection notification, or any kind of operation that can be best handled by the application. In this article, our focus will be on COM based notification, which is better.

Background

There exists very few articles on Smart Device connection notifications in .NET, especially in VB.NET. We wanted to get notifications when a desktop machine is connected with a Windows CE - based device. We could not find code in VB.NET, and finally decided to write it ourselves. We used COM based notifications for getting the Connection and Disconnection events.

Getting Started

To get started, unzip the sample code and project supplied with this article. Open the solution in Visual Studio 2005. The application contains two significant files: RegisterIDccManSink.vb and clsIDccMan.vb. Please note that ActiveSync must be installed on your desktop machine (ActiveSync can be downloaded from the Internet). For getting the connection notification, you have to follow these steps:

  • Run the application.
  • Click on the menu Tools -> Device Emulator Manager in Visual Studio 2005.
  • Select "Pocket PC 2003 SE Emulator" and click on Action - > Connect.
  • Select "Pocket PC 2003 SE Emulator" and click on Action - > Cradle.
  • When the status changes to Connected in ActiveSynk, press the Register button.
  • Now, try Cradle / Uncradle in the Action menu in the Device Emulator Manager.

Using the Code

Open the clsIDccMan.vb file in the code window. The file consists of the definitions of DccMan, DccManSink and the interfaces, IDccMan and IDccManSink. This file contains an import statement:

Imports System.Runtime.InteropServices

This import statement is needed to define the COM attributes. The delegates mentioned below are used to register the events which will be raised on Connection and Disconnection. The ComVisible attribute is used so that these delegates may be visible in COM.

<Serializable()> <ComVisible(True)> Public Delegate Sub ActiveHandler()

<Serializable()> <ComVisible(True)> Public Delegate Sub DisconnectHandler()

This class is used to get the instance of IDccMan. The implementation of this class exists in the ActiveSync Connection Manager. We can see that a key exists corresponding to the "499C0C20-A766-11cf-8011-00A0C90A8F78" in Registry.

<ComImport(), Guid("499C0C20-A766-11cf-8011-00A0C90A8F78")> _
Public Class DccMan
End Class

This interface is used to get all the methods available in IDccMan. With the help of the IDccMan::Advise method, we can register IDccManSink.

<ComImport(), Guid("A7B88841-A812-11cf-8011-00A0C90A8F78"), _
  InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IDccMan
    Function Advise(ByVal pDccSink As IDccManSink, _
                    ByRef dwContext As Int32) As Int32
    Function Unadvise(ByVal dwContext As Int32) As Int32
    Sub ShowCommSettings()
    Sub AutoconnectEnable()
    Sub AutoconnectDisable()
    Sub ConnectNow()
    Sub DisconnectNow()
    Sub SetIconDataTransferring()
    Sub SetIconNoDataTransferring()
    Sub SetIconError()
End Interface

This interface is used to get all the methods available in the IDccManSink.

<Guid("A7B88840-A812-11cf-8011-00A0C90A8F78"), _
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IDccManSink
    <PreserveSig()> Function OnLogIpAddr(<InAttribute()> ByVal _
                          dwIpAddr As Int32) As Int32
    <PreserveSig()> Function OnLogTerminated() As Int32
    <PreserveSig()> Function OnLogActive() As Int32
    <PreserveSig()> Function OnLogInactive() As Int32
    <PreserveSig()> Function OnLogAnswered() As Int32
    <PreserveSig()> Function OnLogListen() As Int32
    <PreserveSig()> Function OnLogDisconnection() As Int32
    <PreserveSig()> Function OnLogError() As Int32
End Interface

DccManSink is the main class. An object of this class is sent to the ActiveSync Connection Manager to get the notification on Connection / Disconnection. When the connection between the desktop computer and the device is established, the Connection Manager calls the IDccManSink::OnLogListen method. Once the remote connection services of both the desktop computer and the device respond, the Connection Manager calls the IDccManSink::OnLogAnswered method. When the Connection Manager has detected the communications interface, it calls the IDccManSink::OnLogActive method. Now, once the connection is established between the device and the Connection Manager, the Connection Manager calls the IDccManSink::OnLogIpAddr method. Finally, the IDccManSink::OnLogIpAddr method is invoked, and this completes the connection.

<Guid("C6659361-1625-4746-931C-36014B146679")> _
Public Class DccManSink
    Implements IDccManSink
    Public Event Active As ActiveHandler
    Public Event Disconnect As DisconnectHandler
    Public Function OnLogActive() As Int32 _
           Implements IDccManSink.OnLogActive
        RaiseEvent Active()
    End Function

    Public Function OnLogAnswered() As Int32 _
           Implements IDccManSink.OnLogAnswered

    End Function

    Public Function OnLogDisconnection() As Int32 _
           Implements IDccManSink.OnLogDisconnection
        RaiseEvent Disconnect()
    End Function

    Public Function OnLogError() As Int32 Implements IDccManSink.OnLogError
    End Function

    Public Function OnLogInactive() As Int32 _
           Implements IDccManSink.OnLogInactive
    End Function

    Public Function OnLogIpAddr(ByVal dwIpAddr As Int32) _
           As Int32 Implements IDccManSink.OnLogIpAddr
    End Function

    Public Function OnLogListen() As Int32 Implements IDccManSink.OnLogListen
    End Function

    Public Function OnLogTerminated() As Int32 _
           Implements IDccManSink.OnLogTerminated
    End Function
End Class

Open the RegisterIDccManSink.vb file in the code window. The file consists of two button click events, which are used to register and unregister the IDccManSink in Connection Manager. In the btnRegister button Click event (btnRegister_Click), we initialize the objects of IDccMan, IDccManSink, DccMan, and DccManSink. The methods are then registered in the events that will be executed on Connection/Disconnection. With the help of the line, objIDccMan.Advise(objDccManSink, intAdvaiceReturn), we register the object of DccManSink which implements IDccManSink. Here, we are passing the object of DccManSink and an integer type variable. This variable will be used to unregister the events.

Private Sub btnRegister_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnRegister.Click
    'To create the object of DccMan class.
    'It is used to get the object of IDccMan
    'becuase we can not create the object of interface directly.
    Dim objDccMan As DccMan = New DccMan()
    'To create the object of IDccMan class.
    objIDccMan = CType(objDccMan, IDccMan)
    'To create the object of DccManSink class. 
    'It is used to get the object of IDccManSink
    Dim objDccManSink As DccManSink = New DccManSink()
    'To create the object of IDccManSink
    'Dim objIDccManSink As IDccManSink = _
          CType(objDccManSink, IDccManSink)
    'To initialize the event handlers.
    AddHandler objDccManSink.Active, AddressOf OnConnection
    AddHandler objDccManSink.Disconnect, AddressOf OnDisConnection
    'To register the IDccManSink
    objIDccMan.Advise(objDccManSink, intAdvaiceReturn)
End Sub

We can call the UnAdvice method of DccManSink to deregister DccManSink.

'To unregister the IDccManSink
objIDccMan.Unadvise(intAdvaiceReturn)

Summary

This example was intended to provide an example with the help of which we can get the notification on Connection and Disconnection, when any desktop machine is connected with Windows CE- based devices. I used it in my application for displaying the connection status between the desktop machine and the device.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here