簡體   English   中英

使用NetworkInterface.Name時出現問題

[英]Problem working with the NetworkInterface.Name

我正在使用以下代碼來檢測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

第二個代碼功勞: 在這里回答。

我修改了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;
}

您的問題是實例名稱與您從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;
    }

根據在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.

似乎您沒有創建類別,也沒有等待性能計數器在讀取數據之前收集數據的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM