转:关于使用OpenNetCF完成windows mobile上的wifi通信

原文:http://www.cnblogs.com/aga-j/archive/2010/08/09/1795375.html

最近接到任务,基本要求是开发一个windows mobile平台上的wifi交互程序,一开始上面的人把需求定义错了,结果我做的东西全部从头来过,而最终的要求就是要程序能在后台运行,然后自动打开wifi,自动选择接入点进行连接。

   google得知可以使用OpenNetCF的OpenNETCF.Net.NetworkInformation命名空间里的WirelessZeroConfigNetworkInterface和AccessPoint来完成。然而不管是在OpenNetCF还是在其他牛人的blog里,都只有使用这个类库来进行搜索周围的热点信息,没有提供connect上热点的信息。一开始在使用WirelessZeroConfigNetworkInterface的connect(stringSSID)时总是出错,所以就怀疑参数传入是不是Access Point的名字,最后经过考证也就是我前面这篇文章关于OpenNETCF.Net.NetworkInformation命名空间的WirelessNetworkInterface类的Connect函数问题介绍的,的确是传入AccessPoint的Name。connect耽搁了我一段时间,我始终搞不懂为什么会出错,所以不尝试通过其他办法来完成connect,知道研究生师兄叫我跟他一起研究,他把我的程序和我给他的OpenNetCF的类库网址拿去研究后,过了两三天就跟我说能连上了,我感觉真是太厉害了,问了他怎么做,他说不用connect函数,用另一个函数叫做ConnectToPreferredNetwork,既然这里是用preferredNetwork,那么要使用这个函数前就要把找到的accesspoint加到preferredNetwork里面,我按着这样的思路做了,结果也可以,其实本来我也想过这样做,但是就是搞不明白为什么connect不能用,所以也没继续研究能不能这样做,知道这样可以连接后,我仍然想知道为什么connect不行,看了OpenNetCF的函数的简要介绍,

http://www.opennetcf.com/library/sdf/

2010080900100341.jpg

注意到connect是连接到access point

2010080900102964.jpg

而ConnectToPreferredNetwork是连接到一个已经配置好的无线网络

熟悉无线网络方面的人应该很清楚我之前错在哪里,而我直到我完成了程序后才知道原来接入无线网络前要对无线热点先进行一些配置,这些在后面的程序中会提到。

    好了,说了这么多废话,现在就开始建一个在windows mobile上操作wifi的程序吧。

 

1 首先建个智能设备项目的工程,然后往里面引用2010080900104325.jpg这四个外部引用,这些dll是OpenNETCF 2.3版里面的dll,要使用的话可以去免费下载Download the Community Edition (Free)

安装后找找dll就行了。这4个dll其实在编码中只会用到OpenNetCF.NET中的NetworkInformation命名空间

 

2 先讲讲怎么打开wifi吧,网络上流传着好多打开wifi的通用代码,我也copy了一份,

001static private string keyValue = null;
002 
003public enum CEDEVICE_POWER_STATE
004 
005{
006 
007PwrDeviceUnspecified = -1,
008 
009/* D0 = 0,
010 
011D1,
012 
013D2,
014 
015D3,
016 
017D4,
018 
019*/ FullOn = 0,
020 
021LowPower = 1,
022 
023Standby = 2,
024 
025Sleep = 3,
026 
027Off = 4,
028 
029PwrDeviceMaximum
030 
031}
032 
033[DllImport("coredll.dll")]
034 
035public static extern int DevicePowerNotify(string device, CEDEVICE_POWER_STATE state, int flags);
036 
037[DllImport("coredll.dll")]
038 
039public static extern int SetDevicePower(string pvDevice, int df, CEDEVICE_POWER_STATE ds);
040 
041[DllImport("coredll.dll")]
042 
043unsafe public static extern int GetDevicePower(string pvDevice, int df, CEDEVICE_POWER_STATE* pds);
044 
045static private void setKeyValue()
046 
047{
048 
049string wifiGUID = "{98C5250D-C29A-4985-AE5F-AFE5367E5006}";
050 
051string keyName = "System\\CurrentControlSet\\Control\\POWER\\State";
052 
053RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(keyName);
054 
055foreach (string val in registryKey.GetValueNames())
056 
057{
058 
059if (val.IndexOf(wifiGUID) != -1)
060 
061{
062 
063keyValue = val;
064 
065break;
066 
067}
068 
069}
070 
071registryKey.Close();
072 
073}
074 
075/// <summary>
076 
077/// "{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\TNETWLN1"
078 
079/// </summary>
080 
081static unsafe public void wifi_power_on()
082 
083{
084 
085try
086 
087{
088 
089if (keyValue != null)
090 
091{
092 
093DevicePowerNotify(keyValue, CEDEVICE_POWER_STATE.FullOn, 1);
094 
095SetDevicePower(keyValue, 1, CEDEVICE_POWER_STATE.FullOn);
096 
097}
098 
099}
100 
101catch (Exception ex)
102 
103{
104 
105}
106 
107}

主要是利用了DevicePowerNotify和SetDevicePower这两个Windows CE 5.0里面的API,然后传入设备名,而wifi设备名则是通过在注册表里面获得。还有一个关闭wifi的,这里就不赘述了,而打开wifi差不多

 

   3来到这里,我们就可以自己试下调用这个函数,然后看看wifi有没有被打开,然后接下来就是connect的问题了。WirelessZeroConfigNetworkInterface对象有个PreferredAccessPoints的字段,这个字段保存的就是你之前所使用过的wifi接入点,注意是连接过的,而不是你找到的,因为找到了accesspoint后如果没有进行连接,是不会存放到PreferredAccessPoints字段里面,所以我们可以直接使用PreferredAccessPoints里面的accesspoint的名字作为参数传入前面说的ConnectToPreferredNetwork(因为满足了already-configured的要求),而如果仅仅将找到的热点(不在PreferredAccessPoints或者说没经过连接的,直接传入ConnectToPreferredNetwork,那就会报错),所以从这里我们可以看出,要连接上某个无线网络,实际上要经过一层configure的。而我们要把找到的热点链接上那怎么办的,那就要依靠WirelessZeroConfigNetworkInterface对象的AddPreferredNetwork函数了,把找到的未配置或者已经配置的accesspoint通过AddPreferredNetwork加入到PreferredNetwork里面,然后再调用ConnectToPreferredNetwork,就可以完成连接了。

01while (count == 0)
02 
03{
04 
05collection = m_wzc.NearbyAccessPoints;
06 
07count = collection.Count;
08 
09}
10 
11MessageBox.Show(count.ToString());
12 
13foreach (AccessPoint ap in collection)
14 
15{
16 
17if (ap.AuthenticationMode == AuthenticationMode.Open)
18 
19{
20 
21MessageBox.Show( m_wzc.AddPreferredNetwork(ap).ToString());
22 
23}
24 
25}

可以看到,上面的代码,我用了一个while来才NearbyAccessPoints的查找,这是因为OpenNetCF里这个字段有个bug,不一定每次m_wzc.NearbyAccessPoints都能返回accesspoint的集合,而且如果你仅仅靠判断NearbyAccessPoints是否为空也是不行的,

while (collection == null)

{

collection = m_wzc.NearbyAccessPoints;

}

它会返回一个不会null的集合对象,但是里面其实是空的。结果你拿不到半个access point

 

    4 最后,这个命名空间,这些类还有好多功能可以实现,比如获得access point的信号状态啊,有无使用加密啊什么的,这些有兴趣或者需要的话就自己研究了,下面附上一个简单的程序。 testWifi.rar

转载于:https://www.cnblogs.com/lanru/archive/2010/08/25/1807865.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值