【问题标题】:Get the properties of the current network connection获取当前网络连接的属性
【发布时间】:2013-10-07 23:39:29
【问题描述】:

您如何确定或检查当前网络连接的连接配置文件(如果有)?

具体来说,我需要确定当前连接是到私有网络还是公共网络,并从那里确定是打开还是关闭网络发现。

似乎可以通过 Windows.Networking.Connectivity.NetworkInformation.GetConnectionProfiles()NetworkInformation.GetInternetConnectionProfile() 函数在 Windows 应用商店应用程序中轻松获得此信息,但这是必须在 Win 7 和 Server 2008 上运行的标准桌面应用程序以及 Win 8 和 Server 2012。

Enumerating the NICs 在机器上不是问题,但这并不能解决我的问题 - 我需要获取连接的属性,而不是物理设备

.Net 框架有没有内置的方法来做到这一点?或者它可以用 WMI 完成吗?或者作为一种粗略的选择,可以通过调用netsh 命令来完成(尽管这似乎取决于dot3svc 和/或wlansvc 服务正在运行)?

【问题讨论】:

标签: c# networking network-programming


【解决方案1】:

您可以为此目的使用Network List Manager API,从 C# import Network List Manager Type Library 中使用它(直接编译下面的示例,取消选中 Embed interop types in reference properties)。

然后你必须枚举所有连接的网络,因为可能不止一个,例如现在我连接到互联网和 VPN。然后对于所有连接的网络调用GetCategory() API,它返回NLM_NETWORK_CATEGORY(私有、公共或域)。

这里是示例代码:

  var manager = new NetworkListManagerClass();
  var connectedNetworks = manager.GetNetworks(NLM_ENUM_NETWORK.NLM_ENUM_NETWORK_CONNECTED).Cast<INetwork>();
  foreach (var network in connectedNetworks)
  {
    Console.Write(network.GetName() + " ");
    var cat = network.GetCategory();
    if (cat == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PRIVATE)
      Console.WriteLine("[PRIVATE]");
    else if (cat == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PUBLIC)
      Console.WriteLine("[PUBLIC]");
    else if (cat == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED)
      Console.WriteLine("[DOMAIN]");
  }      
  Console.ReadKey();

对于网络发现,您必须使用防火墙 API 并参考 COM 库 NetFwTypeLib 并获取 INetFwProfile 用于活动配置文件,然后在服务中有文件共享、网络发现和远程桌面服务,如果这些服务是布尔标志启用。这是示例代码:(只是警告您,我没有在生产中使用下面的代码,我只是在探索这个 API)

  Type objectType = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
  var man = Activator.CreateInstance(objectType) as INetFwMgr;
  /// get current profile 
  INetFwProfile prof = man.LocalPolicy.CurrentProfile;
  Console.WriteLine("Current profile ");
  ShowProfileServices(prof);

以及显示配置文件服务的方法。

private static void ShowProfileServices(INetFwProfile prof)
{
  var services = prof.Services.Cast<INetFwService>();
  var sharing = services.FirstOrDefault(sc => sc.Name == "File and Printer Sharing");
  if (sharing != null)
    Console.WriteLine(sharing.Name + " Enabled : " + sharing.Enabled.ToString());
  else
    Console.WriteLine("No sharing service !");

  var discovery = services.FirstOrDefault(sc => sc.Name == "Network Discovery");

  if (discovery != null)
    Console.WriteLine(discovery.Name + " Enabled : " + discovery.Enabled.ToString());
  else
    Console.WriteLine("No network discovery service !");

  var remoteDesktop = services.FirstOrDefault(sc => sc.Name == "Remote Desktop");
  if (remoteDesktop != null)
    Console.WriteLine(remoteDesktop.Name + " Enabled : " + remoteDesktop.Enabled.ToString());
  else
    Console.WriteLine("No remote desktop service !");
}

【讨论】:

  • 感谢您的回答,它解决了我的部分问题(我不确定“网络发现”设置是否容易获得)。
  • 哦,没看到,我玩过一些防火墙 API,有办法通过它,我会更新我的答案
  • 很好的答案,这是我需要的一切:)
  • 我建议将 Embed Interop Types 设置为 true。您可以通过简单地从var manager = new NetworkListManagerClass();... 中删除“Class”来避免更改它,因此该行应该改为var manager = new NetworkListManager();。然后你可以最小化这个 COM 引用引入的依赖。
  • 感谢您的回答。我的 Windows 语言是土耳其语,sc.Name 是“Dosya ve Yazıcı paylaşımı” :) 所以更喜欢 sc.Type == NET_FW_SERVICE_TYPE_.NET_FW_SERVICE_FILE_AND_PRINT
【解决方案2】:

我知道这个问题已经很老了,但我最近遇到了这个问题 - 如何使用 Windows 运行时 API 中的 Windows.Network.Connectivity 在 C# 中获取网络类别(私有或公共)。

几乎所有内容都与网络相关,但我找不到网络类别。

解决方案是 NetworkTypes 枚举。

https://docs.microsoft.com/en-us/uwp/api/windows.networking.connectivity.networktypes?view=winrt-22000

只需检查返回的类型是否有标记 PrivateNetwork。如果是 - 则不是私有的,如果不是 - 它是公开的。

示例代码如下:

var adapters = NetworkInterface.GetAllNetworkInterfaces();
var upNetworkInterfaces = adapters.Where(x =>
    x.Supports(NetworkInterfaceComponent.IPv4) &&
    x.NetworkInterfaceType is NetworkInterfaceType.Ethernet or NetworkInterfaceType.Wireless80211);
foreach (var adapter in upNetworkInterfaces)
{
    var hostname = NetworkInformation.GetHostNames()
        .FirstOrDefault(x =>
            x.IPInformation != null &&
            string.Equals(x.IPInformation.NetworkAdapter.NetworkAdapterId.ToString(),
                adapter.Id.Replace("{", string.Empty).Replace("}", string.Empty),
                StringComparison.InvariantCultureIgnoreCase));

    if (hostname is not null)
    {
        var networkTypes = hostname.IPInformation.NetworkAdapter.NetworkItem.GetNetworkTypes();
        var privateNetwork = networkTypes.HasFlag(NetworkTypes.PrivateNetwork)
            ? NetworkAccessibilityLevel.Private
            : NetworkAccessibilityLevel.Public;
    }
}

【讨论】:

    猜你喜欢
    • 2014-05-27
    • 2015-11-30
    • 2011-06-08
    • 2012-05-29
    • 2015-11-09
    • 2021-04-11
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多