There are two ways that a desktop application can get notification when a Windows CE-based device gets connected with the desktop application.
- Registry based notification
Registry based notification has two predefined events,
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.
- 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.
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.
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
DccManSink and the interfaces,
IDccManSink. This file contains an import statement:
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
This interface is used to get all the methods available in
IDccMan. With the help of the
IDccMan::Advise method, we can register
<ComImport(), Guid("A7B88841-A812-11cf-8011-00A0C90A8F78"), _
Public Interface IDccMan
Function Advise(ByVal pDccSink As IDccManSink, _
ByRef dwContext As Int32) As Int32
Function Unadvise(ByVal dwContext As Int32) As Int32
This interface is used to get all the methods available in the
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
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.
Public Class DccManSink
Public Event Active As ActiveHandler
Public Event Disconnect As DisconnectHandler
Public Function OnLogActive() As Int32 _
Public Function OnLogAnswered() As Int32 _
Public Function OnLogDisconnection() As Int32 _
Public Function OnLogError() As Int32 Implements IDccManSink.OnLogError
Public Function OnLogInactive() As Int32 _
Public Function OnLogIpAddr(ByVal dwIpAddr As Int32) _
As Int32 Implements IDccManSink.OnLogIpAddr
Public Function OnLogListen() As Int32 Implements IDccManSink.OnLogListen
Public Function OnLogTerminated() As Int32 _
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
Click event (
btnRegister_Click), we initialize the objects of
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
Dim objDccMan As DccMan = New DccMan()
objIDccMan = CType(objDccMan, IDccMan)
Dim objDccManSink As DccManSink = New DccManSink()
AddHandler objDccManSink.Active, AddressOf OnConnection
AddHandler objDccManSink.Disconnect, AddressOf OnDisConnection
We can call the
UnAdvice method of
DccManSink to deregister
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.