8

How do you determine or examine the connection profile of the current network connection (if any)?

Specifically, I need to determine if the current connection is to a private or public network, and from there determine whether network discovery is turned on or off.

It seems like this information is readily available in a Windows Store app via the Windows.Networking.Connectivity.NetworkInformation.GetConnectionProfiles() or NetworkInformation.GetInternetConnectionProfile() functions, but this is a standard desktop app that must run on Win 7 and Server 2008 as well as Win 8 and Server 2012.

Enumerating the NICs on a machine is not a problem, but this doesn't solve my issue - I need to get the properties of the connection, not the physical device.

Is there an inbuilt way to do this with the .Net framework? Alternatively can it be done with WMI? Or as a crude alternative, can it be done by invoking the netsh command (although this seems to depend on the dot3svc and/or wlansvc services to be running)?

4

2 回答 2

12

您可以为此目的使用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 !");
}
于 2013-10-08T00:24:51.087 回答
1

我知道这个问题已经很老了,但我最近遇到了这个问题 - 如何使用 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;
    }
}
于 2021-10-14T08:18:58.490 回答