处理桌面计算机和 Windows CE 设备之间的连接通知





5.00/5 (4投票s)
本文介绍如何接收 Windows CE 设备连接或断开与桌面机的通知。
引言
桌面应用程序可以通过两种方式在 Windows CE 设备连接到桌面应用程序时接收通知。
- 基于注册表的通知
基于注册表的通知有两个预定义的事件:
AutoStartOnConnect
和AutoStartOnDisconnect
,每个事件都有自己的注册表项。我们可以注册与注册表项关联的命令行。每当设备连接到桌面机时,将触发AutoStartOnConnect
事件,并执行该事件下注册的所有命令行。同样,每当设备与桌面机断开连接时,将触发AutoStartOnDisconnect
事件,并执行AutoStartOnDisconnect
键下方的所有命令行。有关更多详细信息,请参阅此 MSDN 链接:基于注册表的通知。
- 基于 COM 的通知
它包括两个接口:由 Rapi.dll 提供的
IDccMan
,以及由需要通知的应用程序实现的IDccManSink
。这些接口处理连接和断开连接的通知。有关更多详细信息,请参阅以下链接:基于 COM 的通知。
这两种方法的基本区别在于,基于注册表的通知会导致程序运行,但我们无法在应用程序中获得通知;而在基于 COM 的通知中,您可以控制连接管理器,注册和注销连接通知,或执行任何最适合应用程序处理的操作。在本文中,我们将重点关注基于 COM 的通知,它更好。
背景
关于 .NET 中智能设备连接通知的文章非常少,尤其是在 VB.NET 中。我们想在桌面机连接到 Windows CE 设备时获得通知。我们在 VB.NET 中找不到代码,最终决定自己编写。我们使用基于 COM 的通知来获取连接和断开连接事件。
入门
要开始,请解压缩本文提供的示例代码和项目。在 Visual Studio 2005 中打开解决方案。该应用程序包含两个重要文件:RegisterIDccManSink.vb 和 clsIDccMan.vb。请注意,您的桌面机上必须安装 ActiveSync(可以从 Internet 下载 ActiveSync)。要获取连接通知,您需要执行以下步骤:
- 运行应用程序。
- 在 Visual Studio 2005 中,单击菜单“工具”->“设备模拟器管理器”。
- 选择“Pocket PC 2003 SE 模拟器”,然后单击“操作”->“连接”。
- 选择“Pocket PC 2003 SE 模拟器”,然后单击“操作”->“Cradle”(连接)。
- 当 ActiveSynk 中的状态变为“已连接”时,按“注册”按钮。
- 现在,尝试在设备模拟器管理器中的“操作”菜单中进行“Cradle”(连接)/“Uncradle”(断开连接)。
Using the Code
在代码窗口中打开 clsIDccMan.vb 文件。该文件包含 DccMan
、DccManSink
以及接口 IDccMan
和 IDccManSink
的定义。该文件包含一个导入语句:
Imports System.Runtime.InteropServices
此导入语句对于定义 COM 属性是必需的。下面的委托用于注册将在连接和断开连接时引发的事件。ComVisible
属性用于使这些委托在 COM 中可见。
<Serializable()> <ComVisible(True)> Public Delegate Sub ActiveHandler()
<Serializable()> <ComVisible(True)> Public Delegate Sub DisconnectHandler()
此类用于获取 IDccMan
的实例。此类的实现存在于 ActiveSync 连接管理器中。我们可以看到注册表中存在一个与“499C0C20-A766-11cf-8011-00A0C90A8F78”对应的键。
<ComImport(), Guid("499C0C20-A766-11cf-8011-00A0C90A8F78")> _
Public Class DccMan
End Class
此接口用于获取 IDccMan
中所有可用方法。通过 IDccMan::Advise
方法,我们可以注册 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
此接口用于获取 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
是主类。该类的对象被发送到 ActiveSync 连接管理器,以获取连接/断开连接的通知。当桌面计算机和设备之间的连接建立时,连接管理器会调用 IDccManSink::OnLogListen
方法。一旦桌面计算机和设备的远程连接服务响应,连接管理器就会调用 IDccManSink::OnLogAnswered
方法。当连接管理器检测到通信接口时,它会调用 IDccManSink::OnLogActive
方法。现在,一旦设备和连接管理器之间的连接建立,连接管理器就会调用 IDccManSink::OnLogIpAddr
方法。最后,调用 IDccManSink::OnLogIpAddr
方法,连接完成。
<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
在代码窗口中打开 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
我们可以调用 DccManSink
的 UnAdvice
方法来注销 DccManSink
。
'To unregister the IDccManSink
objIDccMan.Unadvise(intAdvaiceReturn)
摘要
本示例旨在提供一个示例,通过该示例,我们可以在任何桌面机连接到 Windows CE 设备时获取连接和断开连接的通知。我在我的应用程序中使用了它来显示桌面机与设备之间的连接状态。