使用 NetworkInterface.Name 时出现问题

发布于 2024-10-01 18:21:48 字数 5410 浏览 4 评论 0原文

我正在使用以下代码来检测我的电脑上网络接口卡的名称。我正在使用 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 获取他的答案此处

I am using following code to detect the name of the Network Interface Card on my PC. I am using a USB Modem.

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();
    }
}

I am passing the result to the below given class to calculate the bytes consumption during internet traffic:

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;
    }
}

The first code works fine. It detects my modem as "MBlaze USB Modem", but when the control reaches to the second code with following line:

float bandwidth = bandwidthCounter.NextValue();

it displays error:

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: 

What is the problem?

I won't forget to give the credit to the authors of both the code.

First code credit: Keyvan Nayyeri

Second code credit: entens for his answer here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扛刀软妹 2024-10-08 18:21:48

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

不过,Windows 将替换特殊字符,因此您应该注意这一点。可以在 MSDN 页面找到 PerformanceCounter.InstanceName 属性。

我还对 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;
}

I modified my NIC finding code to return result.Description instead of result.Name. This should give the full interface name used as the InstanceName.

Windows will replace special characters however, so you should be aware of that. Which may be found at the MSDN page for the PerformanceCounter.InstanceName property.

I also made some modifications to the code from Keyvan Nayyeri to condition the input string to match expected instance names. Also, I incorporated Aliostad's code for searching the category for a matching name, but I only throw an exception if the InstanceName does not exist.

    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;
}
述情 2024-10-08 18:21:48

您的问题是实例名称与您从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;
    }

Your problem is that the instance name is a bit different from the name you get from the ReturnNIC and you are using netwrokCard in all places. I have modified the code a bit and now it works for me:

    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;
    }
安人多梦 2024-10-08 18:21:48

根据 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.

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

According to the code presented at 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.

It does not appear that you are creating the category nor waiting a duration of time for the performance counter to collect data prior to reading data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文