8

I have been trying to get the total CPU usage of windows PC (Windows 7 running .Net 4.5) in C#. It looks like using PerformanceCounter should be able to meet my needs.

I wrote some trial code based on the three links below (and checking the MSDN pages), this was the most basic version:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace EntropyProject
{
    class Program
    {
        static void Main(string[] args)
        {
            PerformanceCounter cpuCounter;

            cpuCounter = new PerformanceCounter();
            cpuCounter.CategoryName = "Processor";
            cpuCounter.CounterName = "% Processor Time";
            cpuCounter.InstanceName = "_Total";

            while(true)
            {
                try
                {
                    float firstValue = cpuCounter.NextValue();
                    System.Threading.Thread.Sleep(500);
                    Console.WriteLine("Before getting processor:");
                    float currentCpuUsage = cpuCounter.NextValue();
                    Console.WriteLine("After getting processor:");
                    System.Threading.Thread.Sleep(1000); 
                    Console.WriteLine(currentCpuUsage);
                }
                catch (Exception e)
                {
                    Console.WriteLine("\n{0}\n", e.Message);
                }

                System.Threading.Thread.Sleep(10000);
            }
        }
    }
}

Whenever NextValue is called the exception error below is triggered. This appears to be a common problem with an issue with performance counter values.

Cannot load Counter Name data because an invalid index '' was read from registry

Most recommended solutions suggest that you rebuild the corrupted items using lodctr in a raised command window as admin. However, I was wanting to use the PerformanceCounters in a program that would be released to a large number of people and so would be inappropriate to expect them to rebuild their PerformanceCounters using the command window.

Questions:

  1. Why is this exception error occurring?
  2. How do you properly use PerformanceCounter otherwise?
  3. How can I avoid getting my program users to have to open a cmd window and rebuild their performance counters?

Sources:

  1. How to get CPU usage in C

  2. Get current cpu utilisation in

  3. How can I get the total CPU usage?

Similar Question about the error when accessing counter name asked by Annie Sheikh

Djordje Nedovic
  • 559
  • 8
  • 20
Luke
  • 1,077
  • 13
  • 33
  • 1
    possible duplicate of [Cannot load Counter Name data because an invalid index -Exception](http://stackoverflow.com/questions/17980178/cannot-load-counter-name-data-because-an-invalid-index-exception) – DonBoitnott Feb 02 '15 at 21:00
  • @DonBoitnott Hi Don, the gist of the question is similar. However I wanted to use the PerformanceCounter inside a program to be used by an end user who shouldn't need to go in and change HKEY values from regedit or a command prompt. I'll edit the question to make it more clear. – Luke Feb 02 '15 at 21:15
  • 2
    It's probably not a duplicate, but the permissions part of it seems valid. It has to read from `LOCAL_MACHINE`, a notoriously off-limits section of the registry. – DonBoitnott Feb 02 '15 at 21:23
  • 1
    The user's machine has a nasty registry corruption problem, it happens but is quite rare. The workaround is simple and easily googled, this is not your problem. – Hans Passant Feb 02 '15 at 22:34
  • 1
    @HansPassant It seems to happen on quite a few PCs, all the ones I have tried it on (4) have turned out to have this same corruption which leads me to belief it is common – Luke Feb 02 '15 at 23:49
  • Well, you need to get rid of that program you use that corrupts the registry I guess. It is not common. – Hans Passant Feb 03 '15 at 01:14
  • 1
    @HansPassant not all four computers are owned by myself, and all four are used for very different application. I was under the impression that these counters favoured speed over correctness, meaning they were extremely volatile and any time they are deleted they are liable to corrupt. Atleast in windows version XP and newer. – Luke Feb 03 '15 at 01:51
  • 1
    This is not a total solution but: http://stackoverflow.com/questions/1469764/run-command-prompt-commands. Helps with opening hidden cmd.exe which can be used to send "lodctr /r" (https://technet.microsoft.com/en-us/library/bb490926.aspx) HOWEVER does require use to be logged on as admin so not the complete answer yet – Luke Feb 08 '15 at 21:04

1 Answers1

1

According to the documentation for PerformanceCounter.NextValue, "To read performance counters, you must have administrative privileges." The docs also state that an UnauthorizedAccessException will be thrown if "Code that is executing without administrative privileges attempted to read a performance counter."

But this is a lie. On my Windows 7 environment (64-bit Home Premium edition), running .NET 4.5, I can run your code just fine from a non-raised cmd shell on an Administrator account, or a Standard User account, or even a Guest account.

If you are running into a privilege problem, then most likely no amount of registry fiddling is going to allow your code to run reliably for all users. But I'm unclear why your code works fine on a Guest account with no admin privileges, given what the documentation says.

Another option would be to run "wmic.exe cpu get loadpercentage" and parse the output, as suggested in this answer. Based on my testing this works from either an Administrator or Standard User account, but not from a Guest account.

Community
  • 1
  • 1
yoyo
  • 8,310
  • 4
  • 56
  • 50