使用 .NET Compact Framework 2.0 生成 Wi-Fi 发现应用程序 (转MSDN)
适用于:
Microsoft .NET Compact Framework1.0 版
Microsoft .NET Compact Framework 2.0 版
基于 Windows Mobile 的设备
摘要:了解如何使用 .NET Compact Framework 2.0 和 OpenNETCF 共享的源代码库创建这样一个应用程序,它检测可用的无线网络并从智能设备无线网络适配器检索配置信息。
从 Microsoft Download Center 下载 Build_WiFi_Discover_App_NETCF2.msi。
本页内容
简介
OpenNETCF.org、Smart Device Framework 和 Shared Source License
OpenNETCF.Net 命名空间
后台工作
小结
简介
在当今的移动设备和嵌入设备领域中,无线以太网(即 Wi-Fi)网络适配器越来越普遍,无线热点在大多数技术专业领域几乎无处不在。
遗憾的是,在基于 Windows Mobile 的设备上发现具有标准用户接口 (UI) 和无线零配置(Wireless Zero Configuration,WZC)应用程序编程接口 (API) 集的可用无线网络并非易事。
WZC是 Microsoft 为无线网卡设计的一组标准化接口。如果一个无线卡的驱动程序设计为与 WZC进行交互,则可通过该标准化接口对它进行控制和查询,从而使配置和状态查询代码保持一致,而无需考虑该适配器的制造商。虽然并非所有无线卡都与 WZC兼容,但多数还是与之兼容的,这一高采用率使得 WZC 成为基于 Windows 的桌面计算机和 Windows Mobile操作系统上的一个实际标准。遗憾的是,现在没有关于 Windows CE 中 WZC 接口的文档。
那么嵌入式开发人员能做些什么呢?本文将为您展示如何使用 OpenNETCF.org健壮的共享源代码(而非开放源代码)库编写功能丰富的应用程序,从而显示网络适配器的属性并发现附近的无线接入点。示例应用程序只包含大约 200行手动键入的代码,其中包括注释、空白区域和括号。
如果您对该示例应用程序背后的操作感兴趣,本文提供有"OpenNETCF.Net"命名空间的代码示例下载(如果您引用 OpenNETCF.Net.dll 程序集,该项目运行正常)。本文还考虑到开发人员对库进行四个简单调用时实际发生情况的复杂性。
OpenNETCF.org、Smart Device Framework 和 Shared Source License
每当将第三方软件引入您的解决方案时,都必须分析使用它的益处和风险。因此在您了解有关本示例应用程序的更多知识之前,应该了解有关OpenNETCF.org、Smart Device Framework 和 OpenNETCF Shared Source License的基本知识。
首先,OpenNETCF.org 是一个由 OpenNETCF Consulting, LLP 运作的项目。它是"以开放源代码运动的精神"发起的。该项目为 .NET Compact Framework 开发社区从首批测试版本开始遇到的问题提供解决方案。
OpenNETCF.org项目的主要产品是 Smart Device Framework,它是一个补充 .NET Compact Framework 1.0 版和2.0 版的扩展类集。Smart Device Framework 提供很多可以在整个 .NET Framework中使用的类、属性和方法,以及对特定于 Windows CE 环境的类的较大补充。
Smart Device Framework本质上是一个框架,它使 .NET Compact Framework 开发人员能够以较短的投入市场的时间(相比于单独使用 .NETCompact Framework 而言)提供功能更丰富的解决方案。最棒的是,您可以获取完整的源代码 -源代码完全免费;并且分发许可证非常友好。OpenNETCF Shared Source License(针对 Smart DeviceFramework 1.0 版到 1.4版)对开发人员和业务而言是非常友好的。本文不对它进行详细介绍,只点到为止。不过,该许可证仅一页;语言撰写简练;经过市值达数十亿美元的公司的律师团的审查,证明它可以投入使用。您可以查看完全许可证,它基本上声明了以下内容:
-
如果您同意为最终产品提供某项重要价值,可以使用您的应用程序免费使用和分发 Smart Device Framework。
-
您可以按需(多与少自定)使用 Smart Device Framework。
-
您可以按照提供的方式分发 OpenNETCF 程序集或者将其合并到您自己的产品中。
-
在您的产品文档中,需要声明对 Smart Device Framework 的使用情况。
-
您不能将该框架作为一个独立的产品进行简单编译和销售。
-
您不能将因使用而产生问题的责任归咎于 OpenNETCF。
SmartDevice Framework 已被用户下载近 200,000 次,有将近 2 年的使用历史,其大小(完整格式)几乎与 .NETCompact Framework 1.0 一样大。尽管 Smart Device Framework经过了一定程度的测试,但由于它是一个社区项目,因此可能存在一些 bug,该框架中的某些地方已受到了更多的开发关注。
既然了解了存在的风险,您就可以看到 Smart Device Framework 提供的巨大利益。
OpenNETCF.Net 命名空间
对于本文中的示例应用程序,将只使用 Smart Device Framework 中的一个命名空间:"OpenNETCF.Net"。示例源代码约3,800 行,如果代码正常工作(您将看到确实如此)并且使用了其中的大部分代码(您将这样做),那么您可立即看到这样做能节省数周的开发时间。
该命名空间包含大量用于网络使用的类,包括文件传输协议(File Transfer Protocol,FTP)、网络统计信息和蓝牙。但本文主要介绍以下四个类:Adapter 和 AccessPoint,以及 AdapterCollection 和 AccessPointCollection。顾名思义,后两个类是前两个类的集合类。
图 1 是这些类的一个简单关系图。
Adapter 和 AdapterCollection 类
Adapter类表示系统中任何与以太网兼容的网络适配器。该适配器可以是有线或无线网卡,或者是将以太网层呈现给网络驱动程序接口规范 (NDIS)的其他事物(例如,在通用串行总线 (USB)、串口或红外数据协会(Infrared Data Association,IrDA)上活动的Microsoft ActiveSync 连接)。
如上面图 1 中所示,Adapter 类提供了大量属性,其中大多数属性描述 Internet 协议 (IP) 配置项(如 IP 地址、网关和子网掩码)或无线连接信息(如信号强度)。
本文中的示例使用 Adapter 类显示任何适配器(无线或有线的)的常用适配器配置信息。
AdapterCollection 类只是一个 CollectionBase 派生的类,它为对 Networking.GetAdapters 的调用返回的适配器提供一个容器。
如上面的代码示例所示,您首先需要获取该设备具有的所有 NDIS 适配器的列表,该列表通过从 Networking.GetAdapters 返回的一个 AdapterCollection 类的生成。该示例应用程序启动后,通过调用 UpdateAdapters 可获取一个列表���UpdateAdapters 获取一个 AdapterCollection 类并用适配器名称填充组合框。
void UpdateAdapters()
{
// Get the available adapters
m_adapters = Networking.GetAdapters();
// Clear the combo
cboAdapters.Items.Clear();// Add the adapters
foreach (Adapter adapter in m_adapters)
{
cboAdapters.Items.Add(adapter);
}
}
每次用户更改所选的(或当前的)适配器时,都通过调用 UpdateConfig 使用所选适配器的配置信息更新该 UI,如以下代码示例所示。
void UpdateConfig()
{
tabConfiguration.SuspendLayout();
// Update the adapter's configuration information
lblMACAddress.Text =
BitConverter.ToString(m_currentAdapter.MacAddress);lblIPAddress.Text = m_currentAdapter.CurrentIpAddress;
lblSubnet.Text = m_currentAdapter.CurrentSubnetMask;
lblGateway.Text = m_currentAdapter.Gateway;// Wireless information
bool wireless = m_currentAdapter.IsWireless;
if (wireless)
{
lblIsWireless.Text = "True";
lblWZCCompat.Text =
m_currentAdapter.IsWirelessZeroConfigCompatible.
ToString();
}
else
{
lblIsWireless.Text = "False";
lblWZCCompat.Text = "N/A";
}// Dynamic Host Configuration Protocol (DHCP) information
bool dhcpEnabled = m_currentAdapter.DhcpEnabled;
if (dhcpEnabled)
{
lblDHCPEnabled.Text = "True";
lblLeaseObtained.Text =
m_currentAdapter.LeaseObtained.ToShortDateString();
lblLeaseExpires.Text =
m_currentAdapter.LeaseExpires.ToShortDateString(); ;
mnuRenew.Enabled = true;
}
else
{
lblDHCPEnabled.Text = "False";
lblLeaseObtained.Text = "N/A";
lblLeaseExpires.Text = "N/A";
mnuRenew.Enabled = false;
}tabConfiguration.ResumeLayout();
}
图 2 显示运行在 HP iPAQ H5555 设备上的示例应用程序的 Configuration 选项卡。所选的适配器是内置的 802.11b 控制器。当该设备通过传输控制协议/Internet 协议 (TCP/IP) 上的 ActiveSync 进行连接时,ActiveSync 连接也将枚举为一个适配器。
对于本文的 Wi-Fi 发现目标,此处的重要属性是 IsWirelessZeroConfigCompatible。如果某个无线适配器与 WZC 不兼容,则其大多数属性需要通过专用 API调用(通常不记录或发布)进行访问,从而导致开发人员无法创建自定义实现或软件。然而,如果某个适配器与 WZC兼容(越来越多的适配器都是这样),您可以使用一组标准的 Windows API 获取大量有关该适配器及其所识别的网络接入点的信息。
正如前面提到的,尚未有正式编写的 WZC API 文档。但是 Microsoft Platform Builder 附带有连接到 WZC兼容的适配器的默认网络 UI 的源代码,该源代码还提供了解 API 工作方式的方法(尽管比较有价值),这些 API 可通过 OpenNETCF.Net.AccessPoint 类以用户友好的方式使用。
AccessPoint 和 AccessPointCollection 类
无线网络中令人感兴趣的主要节点是访问点。当您使用一个针对特定适配器的访问点时,它们通常分为两类:该适配器现在可以识别的访问点,以及该适配器过去已经识别并且再次遇到时将优先处理的访问点。这两个列表通常是不同的,但它们通常将包含一些相同的访问点。在 AccessPoint类中,这些访问点分别定义为邻近(通常称为可用的)访问点和首选访问点。访问点的第三个重要术语是关联访问点,它是您目前在本例中运行网络流量所使用的访问点。很有可能没有关联访问点,例如,如果您不在任何访问点的范围内,但如果您与访问点相关联,则关联访问点始终处于邻近访问点列表中。
在该示例中,您获得并显示以下两个列表:首选访问点和可用访问点。对于当前选中的适配器识别的访问点,信号强度以分贝为单位列出,附带一个文字性说明(如 Excellent、Good、Fair 或 Poor)。
在图 3 中您可以看到,当前示例包含两个可用访问点,它们都具有很好的强度,因为它们与这些访问点的距离不足一英尺。AccessPoint 类也有几个其他属性,用于提供有关其功能和隐私的信息。
后台工作
虽然用于制作 WiFiDiscovery 应用程序的代码非常简单,但它掩盖了 OpenNETCF 库中 .NET Compact Framework 层上实际进行的工作。对 Networking.GetAdapters 的调用使用平台调用来调用 iphlpapi.dll 文件的 GetAdaptersInfo 函数,该函数返回一个本机结构数组 - 每个本机结构针对一个注册到系统中的网络适配器(无线或有线)。
这些结构在内部从本机 API 封送为 IP_ADAPTER_INFO 类,这就是 API 返回数据的方式。每个 IP_ADAPTER_INFO 类转换为公开的托管 Adapter 类,以提供所有适配器公开的一般信息(诸如适配器名称、MAC 地址和 IP 配置)。
如果该适配器报告为一个以太网适配器,则随后对该适配器进行查询以查看它是否是无线的,并通过使用平台调用来调用 wzcsapi.dll 文件的 WZCQueryInterface API 以查看它是否支持 WZC 接口。
如果发现某个适配器是无线的,则可以通过该设备的 NDIS 驱动程序(再次使用平台)查询有关它的大量信息。
如果还发现某个适配器与 WZC 兼容,则可以派生更多信息,方法是使用平台调用来调用具有不同参数的 WZCQueryInterface API。例如,您可以查询可用访问点数组或关联访问点数组。
如果您查询邻近访问点,甚至会更复杂,因为平台调用对 NDIS 驱动程序的调用。
作为只用几个简单调用即产生结果的简要示例,当您想找到系统中第一个适配器的邻近访问点时,请看看系统中的数据流。在 WiFiDiscovery.exe 中,代码如下面简单的四行代码所示:
AdapterCollection adapters = Networking.GetAdapters();
adapters[0].IsWireless;
adapters[0].IsWirelessZeroConfigCompatible;
AccessPointCollection aps = adapters[0].NearbyAccessPoints;
图 4 显示该系统中的实际操作。
小结
.NET Compact Framework 和托管代码的目的通常是提高开发人员的工作效率。高工作效率意味着更快地投入市场,具有更丰富的功能集。它意味着较低成本的解决方案,较低的机会成本,以及更多资源可用于其他项目。
虽然本文介绍的示例应用程序没有完整的无线应用程序那么健壮(例如,它不具有针对访问点基础架构的图标,也无法更改访问点关联),但是它的确可以检验生产效率点。通过使用一个免费的共享的源代码库,您已经用不到 200 行的代码创建了一个基本 Wi-Fi发现应用程序。该应用程序显示所有可用的适配器。对于无线适配器,该应用程序显示所有的可用和首选访问点以及它们的信号强度。另外,本文包括了七行代码,用来更新任何适配器的 DHCP 地址(如果期望的结果是一个更基本的 UI,则只需一行代码)。
托管代码并不是每个业务问题的解决方案,C/C++ 肯定有其一席之地,但是在当今快节奏的业务环境中,开发人员必须始终以较高的效率为客户服务。托管代码(外加 MicrosoftVisual Studio 2005 提供的 Rapid Application Development工具)为开发人员在市场中成功竞争提供了一个坚实的基础。