获取网络连接状态(二) IsNetworkAlive

IsNetworkAlive需要服务System Event Notification的支持(系统默认自动启动该服务),且需要安装最新的SDK(如.NET)

浏览:MSDN对IsNetworkAlive的详细描述

由API中翻译:该功能可在Windows XP、2000(或Windows NT 4.0与Internet Explorer 5或更高版本)上使用,在windows95或更高版本上使用Internet Explorer 5或更高版本。所以,一般的系统都是支持的

输出值lpdwFlags

具体类型的详细内容可链接QOCINFO structure

  • NETWORK_ALIVE_LAN=1 局域网(此处并非指有线网)
  • NETWORK_ALIVE_WAN=2 远程访问-拨号访问和vpn访问(此处并非只无线网,按DPI所示,指的是RAS connections)
  • NETWORK_ALIVE_AOL=4 无效的值。。。因为只有Win9x系统才有此第三个选项。参考链接

无线网络的判断:lpdwFlags对是否无线网络,并没有直接的判断。

eg:比如我的电脑环境(有线网络或者wifi网络),获取的flag=1(局域网)

返回值(bool)

  • 当返回值为true,且无错误Code时,表示网络已连接
  • 当返回值为false,且无错误Code时,表示网络未连接

那么,错误Code(异常)怎么获取呢?

获取上一次异常Code-GetLastError

参考链接

此处推荐使用Marshal中的GetLastWin32Error,见如下源代码:

 1     /// <summary>
 2     ///   通过使用平台调用的最后一个非托管函数返回的错误代码返回调用具有 <see cref="F:System.Runtime.InteropServices.DllImportAttribute.SetLastError" /> 标志设置。
 3     /// </summary>
 4     /// <returns>最后一个错误代码设置通过调用 Win32 SetLastError 函数。</returns>
 5     [SecurityCritical]
 6     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
 7     [MethodImpl(MethodImplOptions.InternalCall)]
 8     public static extern int GetLastWin32Error();

GetLastWin32Error可获取最后一个非托管函数的错误Code

 int errCode = Marshal.GetLastWin32Error();

--获取 error code的详细描述信息,可参考https://my.oschina.net/kavensu/blog/264273

值得注意的是,非托管函数声明时,要添加SetLastError=true;如:

1 [DllImport("sensapi.dll", SetLastError = true)]
2 private static extern bool IsNetworkAlive(out int connectionDescription);

网络状态准确性

IsNetworkAlive电脑网络判断不准确,案例:

  1. 电脑配置了虚拟机连接--将当前的以太网禁用后,IsNetworkAlive返回的是有网true -- 将虚拟机的本地网络适配器当成了可用的网络连接,但是电脑其实是没有网络的
  2. 在某些情况下,光纤等坏了,上不了网络,但是走TCP协议可以聊微信QQ,IsNetworkAlive返回的也是有网true

IsNetworkAlive对网络类型判断也不准确,虽然可以通过lpdwFlags枚举值判断网络类型。

无网络时,有可能返回有网:lpdwFlags=1 局域网时,如果当前配置了虚拟机连接之类的,本机无法连接网络时,IsNetworkAlive函数还是会返回true。如下:

  所以,IsNetworkAlive仅可使用简单场景下的网络判断

posted @ 2020-05-27 14:39  唐宋元明清2188  阅读(43)  评论(0编辑  收藏