Introduction
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, 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.
- 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
Dim objDccMan As DccMan = New DccMan()
objIDccMan = CType(objDccMan, IDccMan)
Dim objDccManSink As DccManSink = New DccManSink()
CType(objDccManSink, IDccManSink)
AddHandler objDccManSink.Active, AddressOf OnConnection
AddHandler objDccManSink.Disconnect, AddressOf OnDisConnection
objIDccMan.Advise(objDccManSink, intAdvaiceReturn)
End Sub
We can call the UnAdvice
method of DccManSink
to deregister DccManSink
.
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.