使用NetworkInterface.Name时出现问题

时间:2010-11-13 15:38:12

标签: .net network-programming

我正在使用以下代码来检测我的PC上的网络接口卡的名称。我正在使用USB调制解调器。

public class DetectNIC
{
    public string ReturnNIC()
    {
        List<NetworkInterface> Interfaces = new List<NetworkInterface>();
        foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (nic.OperationalStatus == OperationalStatus.Up)
            {
                Interfaces.Add(nic);
            }
        }

        NetworkInterface result = null;
        foreach (NetworkInterface nic in Interfaces)
        {
            if (result == null)
            {
                result = nic;
            }
            else
            {
                if (nic.GetIPProperties().GetIPv4Properties() != null)
                {
                    if (nic.GetIPProperties().GetIPv4Properties().Index < result.GetIPProperties().GetIPv4Properties().Index)
                        result = nic;
                }
            }
        }
        return result.Name.ToString();
    }
}

我将结果传递给下面给定的类来计算互联网流量期间的字节消耗:

public class ByteCounter
{
    public double GetNetworkUtilization(string networkCard)
    {
        const int numberOfIterations = 10;

        PerformanceCounter bandwidthCounter =
            new PerformanceCounter("Network Interface", "Current Bandwidth", networkCard);

        float bandwidth = bandwidthCounter.NextValue();

        PerformanceCounter dataSentCounter =
            new PerformanceCounter("Network Interface", "Bytes Sent/sec", networkCard);

        PerformanceCounter dataReceivedCounter =
            new PerformanceCounter("Network Interface", "Bytes Received/sec", networkCard);

        float sendSum = 0;
        float receiveSum = 0;

        for (int index = 0; index < numberOfIterations; index++)
        {
            sendSum += dataSentCounter.NextValue();
            receiveSum += dataReceivedCounter.NextValue();
        }

        float dataSent = sendSum;
        float dataReceived = receiveSum;

        double utilization = (8 * (dataSent + dataReceived)) / (bandwidth * numberOfIterations) * 100;
        return utilization;
    }
}

第一个代码工作正常。它将我的调制解调器检测为“MBlaze USB调制解调器”,但是当控件到达第二个代码时,后续行:

float bandwidth = bandwidthCounter.NextValue();

显示错误:

System.InvalidOperationException was unhandled
  Message="Instance 'MBlaze USB Modem' does not exist in the specified Category."
  Source="System"
  StackTrace:
       at System.Diagnostics.CounterDefinitionSample.GetInstanceValue(String instanceName)
       at System.Diagnostics.PerformanceCounter.NextSample()
       at System.Diagnostics.PerformanceCounter.NextValue()
       at LogTraffic.ByteCounter.GetNetworkUtilization(String networkCard) in F:\Projects\LogTraffic\bytecounter.cs:line 15
       at LogTraffic.MainForm.MainForm_Load(Object sender, EventArgs e) in F:\Projects\LogTraffic\MainForm.cs:line 24
       at System.Windows.Forms.Form.OnLoad(EventArgs e)
       at System.Windows.Forms.Form.OnCreateControl()
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmShowWindow(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
       at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Control.set_Visible(Boolean value)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at LogTraffic.Program.Main() in F:\Projects\LogTraffic\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

有什么问题?

我不会忘记将这两个代码的作者都归功于。

第一个代码来源:Keyvan Nayyeri

第二个代码信用:entens代表他的回答here

3 个答案:

答案 0 :(得分:4)

我修改了我的网卡查找代码以返回result.Description而不是result.Name。这应该提供用作InstanceName的完整接口名称。

Windows会替换特殊字符,所以你应该知道这一点。可以在PerformanceCounter.InstanceName属性的MSDN页面找到。

我还对Keyvan Nayyeri的代码进行了一些修改,以调整输入字符串以匹配预期的实例名称。另外,我将Aliostad的代码用于搜索匹配名称的类别,但是如果InstanceName不存在,我只会抛出异常。

    public double GetNetworkUtilization(string networkCard)
{
    const int numberOfIterations = 10;

    // Condition networkCard;
    networkCard = networkCard.Replace("\\", "_");
    networkCard = networkCard.Replace("/", "_");
    networkCard = networkCard.Replace("(", "[");
    networkCard = networkCard.Replace(")", "]");
    networkCard = networkCard.Replace("#", "_");

    PerformanceCounterCategory NetworkInterfaceCatagory =
        PerformanceCounterCategory.GetCategories().Where(c => c.CategoryName.Equals("Network Interface")).FirstOrDefault();

    //// DEBUG: Check this array to see if the network card exists 
    //foreach(string instance in NetworkInterfaceCatagory.GetInstanceNames())
    //{
    //    System.Diagnostics.Debug.Print(instance);
    //}

    if (string.IsNullOrEmpty(NetworkInterfaceCatagory.GetInstanceNames().Where(i => i.Equals(networkCard)).FirstOrDefault()))
        throw new ApplicationException("NIC does not exist in existing performance counters");

    string instanceName = networkCard;

    PerformanceCounter bandwidthCounter =
        new PerformanceCounter("Network Interface", "Current Bandwidth", instanceName);

    PerformanceCounter dataSentCounter =
        new PerformanceCounter("Network Interface", "Bytes Sent/sec", instanceName);

    PerformanceCounter dataReceivedCounter =
        new PerformanceCounter("Network Interface", "Bytes Received/sec", instanceName);

    float bandwidth = bandwidthCounter.NextValue();
    float sendSum = 0;
    float receiveSum = 0;

    for (int index = 0; index < numberOfIterations; index++)
    {
        sendSum += dataSentCounter.NextValue();
        receiveSum += dataReceivedCounter.NextValue();
    }

    float dataSent = sendSum;
    float dataReceived = receiveSum;

    double utilization = (8 * (dataSent + dataReceived)) / (bandwidth * numberOfIterations) * 100;
    return utilization;
}

答案 1 :(得分:2)

您的问题是实例名称与您从ReturnNIC获得的名称有点不同,而您使用的是netwrokCard所有地方。我已经修改了一些代码,现在它适用于我:

    public static double GetNetworkUtilization(string networkCard)
    {
        const int numberOfIterations = 10;
        PerformanceCounterCategory category = null;
        foreach (var performanceCounterCategory in PerformanceCounterCategory.GetCategories())
        {
            if (performanceCounterCategory.CategoryName == "Network Interface")
            {
                category = performanceCounterCategory;
                break;
            }
        }

        string instanceName = category.GetInstanceNames().Where(x=>x.Contains(networkCard)).FirstOrDefault();

        PerformanceCounter bandwidthCounter =
            new PerformanceCounter("Network Interface", "Current Bandwidth", instanceName);

        float bandwidth = bandwidthCounter.NextValue();

        PerformanceCounter dataSentCounter =
            new PerformanceCounter("Network Interface", "Bytes Sent/sec", instanceName);

        PerformanceCounter dataReceivedCounter =
            new PerformanceCounter("Network Interface", "Bytes Received/sec", instanceName);

        float sendSum = 0;
        float receiveSum = 0;

        for (int index = 0; index < numberOfIterations; index++)
        {
            sendSum += dataSentCounter.NextValue();
            receiveSum += dataReceivedCounter.NextValue();
        }

        float dataSent = sendSum;
        float dataReceived = receiveSum;

        double utilization = (8 * (dataSent + dataReceived)) / (bandwidth * numberOfIterations) * 100;
        return utilization;
    }

答案 2 :(得分:0)

根据MSDN system.diagnostics.performancecounter.nextvalue

提供的代码
    // If the category does not exist, create the category and exit.
    // Performance counters should not be created and immediately used.
    // There is a latency time to enable the counters, they should be created
    // prior to executing the application that uses the counters.
    // Execute this sample a second time to use the category.

您似乎没有创建类别,也没有等待性能计数器在读取数据之前收集数据的持续时间。