在开发过程中,经常需要在Windows CE设备与桌面应用程序之间建立连接时获取通知。本文将介绍如何使用COM接口实现这一功能。
注册表通知依赖于两个预定义事件:AutoStartOnConnect和AutoStartOnDisconnect。每个事件都有对应的注册表键值。可以在这些键值下注册命令行,当设备连接到桌面计算机时,AutoStartOnConnect事件将被触发,并执行所有注册的命令行。类似地,当设备从桌面计算机断开连接时,AutoStartOnDisconnect事件将被触发,并执行所有注册的命令行。
COM接口通知包括两个接口:IDccMan和IDccManSink。IDccMan由Rapi.dll提供,IDccManSink由需要通知的应用程序实现。这两个接口处理连接和断开连接的通知。
注册表通知和COM接口通知的主要区别在于,注册表通知运行程序时,无法在应用程序中获取通知,而在COM接口通知中,可以控制连接管理器,注册和注销连接通知,或任何可以由应用程序最佳处理的操作。本文的重点是COM接口通知,它更好。
关于.NET中Smart Device连接通知的文章非常少,特别是在VB.NET中。希望在桌面计算机连接到基于Windows CE的设备时获得通知。找不到VB.NET中的代码,最终决定自己编写。使用COM接口通知来获取连接和断开连接事件。
要开始,请解压缩本文附带的示例代码和项目。在Visual Studio 2005中打开解决方案。应用程序包含两个重要文件:RegisterIDccManSink.vb和clsIDccMan.vb。请注意,必须在桌面计算机上安装ActiveSync(可以从互联网下载ActiveSync)。要获取连接通知,请按照以下步骤操作:
打开clsIDccMan.vb文件。该文件包含DccMan、DccManSink和接口IDccMan和IDccManSink的定义。该文件包含一个导入语句:
Imports System.Runtime.InteropServices
这个导入语句用于定义COM属性。下面提到的委托用于注册在连接和断开连接时将引发的事件。ComVisible属性用于使这些委托在COM中可见。
Public Delegate Sub ActiveHandler()
Public Delegate Sub DisconnectHandler()
此类用于获取IDccMan的实例。此类的实现存在于ActiveSync连接管理器中。可以看到,在注册表中存在一个与"499C0C20-A766-11cf-8011-00A0C90A8F78"对应的键值。
_ Public Class DccMan End Class
此接口用于获取IDccMan中所有可用的方法。借助IDccMan::Advise方法,可以注册IDccManSink。
_ 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
此接口用于获取IDccManSink中所有可用的方法。
_ Public Interface IDccManSink Function OnLogIpAddr(ByVal dwIpAddr As Int32) As Int32 Function OnLogTerminated() As Int32 Function OnLogActive() As Int32 Function OnLogInactive() As Int32 Function OnLogAnswered() As Int32 Function OnLogListen() As Int32 Function OnLogDisconnection() As Int32 Function OnLogError() As Int32 End Interface
DccManSink是主类。将此类的对象发送到ActiveSync连接管理器,以在连接/断开连接时获取通知。当桌面计算机与设备之间的连接建立时,连接管理器调用IDccManSink::OnLogListen方法。一旦桌面计算机和设备的远程连接服务响应,连接管理器调用IDccManSink::OnLogAnswered方法。当连接管理器检测到通信接口时,它调用IDccManSink::OnLogActive方法。现在,一旦设备与连接管理器之间的连接建立,连接管理器调用IDccManSink::OnLogIpAddr方法。最后,调用IDccManSink::OnLogIpAddr方法,这完成了连接。
_ 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
打开RegisterIDccManSink.vb文件。该文件包含两个按钮点击事件,用于在连接管理器中注册和注销IDccManSink。在btnRegister按钮的Click事件(btnRegister_Click)中,初始化IDccMan、IDccManSink、DccMan和DccManSink的对象。然后注册将在连接/断开连接时执行的事件。借助objIDccMan.Advise(objDccManSink, intAdvaiceReturn)行,注册实现IDccManSink的DccManSink对象。在这里,传递DccManSink的对象和一个整型变量。这个变量将用于注销事件。
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
'To unregister the IDccManSink objIDccMan.Unadvise(intAdvaiceReturn)