how to Find CPU usage of a Remote Machine in using C#.NET?

Posted on 2005-04-13
Medium Priority
Last Modified: 2008-01-09
how to Find CPU usage of a Remote Machine in using C#.NET?
Am able to do it with the help of System.diagnostics.PerformanceCounter. But then, am able to get local machine's CPU % properly. But when I tried to get the same of a Remote Computer, am getting the message "Access denied". How to come over this problem programatically? Give me a solution.

Question by:DonRameshSachin
  • 4
  • 3
  • 3
LVL 20

Expert Comment

ID: 13771160
This is a rights problem. The user under which the application is running needs to have (probably) admin rights on the remote machine.
LVL 96

Expert Comment

by:Bob Learned
ID: 13772064
I would suggest WMI:

Such as here:

Performance Management in Windows (WMIC section).

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

LVL 96

Expert Comment

by:Bob Learned
ID: 13772099
If you need a software solution in C#, it is possible, I just don't have any code right now.


Author Comment

ID: 13787887
Hi bob,
 Thanks for your timely effort. It would be more appreciable if u send me a soution (code) ASAP. Mean while I will also look for a suitable code in WMI. Currently am trying to achieve the same with the System.Management Namespace in .NET.  

PS: TheAvenger. thanks for ur effort. I very well know thats because of the access rights problem. All i want is programmetical solution for the same.
LVL 20

Expert Comment

ID: 13788523
You can impersonate your user with another user/password for the part of the code where you check the CPU on the other machine. This means the application needs to know the user name and password of an admin of the other machine. Will this help you? I can provide you with an example how this is done. Note that there is no way to go around security and check the CPU usage without the needed rights.

Author Comment

ID: 13790063
 Thanks for ur comment again. I agree that credential is required to access the remote machine. Assume that i have the Windows user name and pwd. How will I identify the CPU Utilization of the remote machine programetically.

LVL 96

Accepted Solution

Bob Learned earned 2000 total points
ID: 13790191
I haven't tested this in C#, so let me know if you have any problems:

public class WMI_Library

 public class Win32_Processor
   public int Architecture;
   public int Availability;
   public string Caption = string.Empty;
   public int ConfigManagerErrorCode;
   public bool ConfigManagerUserConfig;
   public int CpuStatus;
   public string CreationClassName = string.Empty;
   public int CurrentClockSpeed;
   public int CurrentVoltage;
   public int DataWidth;
   public string Description;
   public string DeviceID;
   public bool ErrorCleared;
   public string ErrorDescription;
   public int ExtClock;
   public int Family;
   public System.DateTime InstallDate;
   public int L2CacheSize;
   public int L2CacheSpeed;
   public int LastErrorCode;
   public int Level;
   public int LoadPercentage;
   public string Manufacturer;
   public int MaxClockSpeed;
   public string Name;
   public string OtherFamilyDescription;
   public string PNPDeviceID;
   public bool PowerManagementSupported;
   public string ProcessorId;
   public int ProcessorType;
   public int Revision;
   public string Role;
   public string SocketDesignation;
   public string Status;
   public int StatusInfo;
   public string Stepping;
   public string SystemCreationClassName;
   public string SystemName;
   public string UniqueId;
   public int UpgradeMethod;
   public string Version;
   public int VoltageCaps;

 private ManagementScope _searchScope;

 public void CreateSearchScope(string computerName, string userName, string password)
   bool isSameMachine = (computerName.Length == 0);
   if (!(isSameMachine)) {
     ManagementPath pathSearch = new ManagementPath(@"\\" + computerName + "\Root\CIMV2");
     _searchScope = new ManagementScope(pathSearch);
     _searchScope.Options.Username = userName;
     _searchScope.Options.Password = password;

 public static Win32_Processor GetCPUInformation(int index)
   ArrayList listCPUs = new ArrayList();
   string query = "Select * From Win32_Processor";
   ManagementObjectSearcher searchCPU = new ManagementObjectSearcher(query);

   if (!(_searchScope == null))
     searchCPU.Scope = _searchScope;

   foreach (ManagementObject entryCurrent in searchCPU.Get)
     Win32_Processor cpuInfo = new Win32_Processor();
     cpuInfo.Architecture = Convert.ToInt32(entryCurrent("Architecture"));
     cpuInfo.Availability = Convert.ToInt32(entryCurrent("Availability"));
     cpuInfo.Caption = entryCurrent("Caption");
     cpuInfo.ConfigManagerErrorCode = Convert.ToInt32(entryCurrent("ConfigManagerErrorCode"));
     cpuInfo.ConfigManagerUserConfig = entryCurrent("ConfigManagerUserConfig");
     cpuInfo.CpuStatus = Convert.ToInt32(entryCurrent("CpuStatus"));
     cpuInfo.CreationClassName = entryCurrent("CreationClassName");
     cpuInfo.CurrentClockSpeed = Convert.ToInt32(entryCurrent("CurrentClockSpeed"));
     cpuInfo.CurrentVoltage = Convert.ToInt32(entryCurrent("CurrentVoltage"));
     cpuInfo.DataWidth = Convert.ToInt32(entryCurrent("DataWidth"));
     cpuInfo.Description = entryCurrent("Description");
     cpuInfo.DeviceID = entryCurrent("DeviceID");
     cpuInfo.ErrorCleared = entryCurrent("ErrorCleared");
     cpuInfo.ErrorDescription = entryCurrent("ErrorDescription");
     cpuInfo.ExtClock = Convert.ToInt32(entryCurrent("ExtClock"));
     cpuInfo.Family = Convert.ToInt32(entryCurrent("Family"));
     cpuInfo.InstallDate = entryCurrent("InstallDate");
     cpuInfo.L2CacheSize = Convert.ToInt32(entryCurrent("L2CacheSize"));
     cpuInfo.L2CacheSpeed = Convert.ToInt32(entryCurrent("L2CacheSpeed"));
     cpuInfo.LastErrorCode = Convert.ToInt32(entryCurrent("LastErrorCode"));
     cpuInfo.Level = Convert.ToInt32(entryCurrent("Level"));
     cpuInfo.LoadPercentage = Convert.ToInt32(entryCurrent("LoadPercentage"));
     cpuInfo.Manufacturer = entryCurrent("Manufacturer");
     cpuInfo.MaxClockSpeed = Convert.ToInt32(entryCurrent("MaxClockSpeed"));
     cpuInfo.Name = entryCurrent("Name");
     cpuInfo.OtherFamilyDescription = entryCurrent("OtherFamilyDescription");
     cpuInfo.PNPDeviceID = entryCurrent("PNPDeviceID");
     cpuInfo.PowerManagementSupported = entryCurrent("PowerManagementSupported");
     cpuInfo.ProcessorId = entryCurrent("ProcessorId");
     cpuInfo.ProcessorType = Convert.ToInt32(entryCurrent("ProcessorType"));
     cpuInfo.Revision = Convert.ToInt32(entryCurrent("Revision"));
     cpuInfo.Role = entryCurrent("Role");
     cpuInfo.SocketDesignation = entryCurrent("SocketDesignation");
     cpuInfo.Status = entryCurrent("Status");
     cpuInfo.StatusInfo = Convert.ToInt32(entryCurrent("StatusInfo"));
     cpuInfo.Stepping = entryCurrent("Stepping");
     cpuInfo.SystemCreationClassName = entryCurrent("SystemCreationClassName");
     cpuInfo.SystemName = entryCurrent("SystemName");
     cpuInfo.UniqueId = Convert.ToInt32(entryCurrent("UniqueId"));
     cpuInfo.UpgradeMethod = Convert.ToInt32(entryCurrent("UpgradeMethod"));
     cpuInfo.Version = entryCurrent("Version");
     cpuInfo.VoltageCaps = Convert.ToInt32(entryCurrent("VoltageCaps"));

     if (cpuInfo.Role == "CPU")


   return listCPUs(index);



WMI_Library lib = New WMI_Library();
WMI_Library.CreateSearchScope(<machine name>, <user name>, <password>);
WMI_Library.CPUInfo info = lib.GetCPUInformation[0];

LVL 20

Expert Comment

ID: 13792101
This is the code for impersonation. The rest you can use as you already have it:

--------------------------------- Helper class ---------------------
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Diagnostics;

[assembly:SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode=true)]
[assembly:PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
namespace MyNamespace
      /// <summary>
      /// Taken from: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSecurityPrincipalWindowsImpersonationContextClassTopic.asp?frame=true
      /// </summary>
      public class ImpersonationHelper
            #region Some DLL imports
            [DllImport("advapi32.dll", SetLastError=true)]
            public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
                  int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

            [DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
            private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource,
                  int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr *Arguments);

            [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
            public extern static bool CloseHandle(IntPtr handle);

            [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
            public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
                  int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

            #region GetErrorMessage
            // GetErrorMessage formats and returns an error message
            // corresponding to the input errorCode.
            public unsafe static string GetErrorMessage(int errorCode)
                  int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
                  int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
                  int FORMAT_MESSAGE_FROM_SYSTEM  = 0x00001000;

                  int messageSize = 255;
                  String lpMsgBuf = "";

                  IntPtr ptrlpSource = IntPtr.Zero;
                  IntPtr prtArguments = IntPtr.Zero;
                  int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
                  if (0 == retVal)
                        throw new Exception("Failed to format message for error code " + errorCode + ". ");

                  return lpMsgBuf;

            [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
            public static WindowsImpersonationContext Impersonate (string domainName, string userName, string password, out WindowsIdentity identity)
                  System.Management.ManagementObject mo = new System.Management.ManagementObject(new System.Management.ManagementPath( ));
                  mo.Scope.Options.EnablePrivileges = true;

                  IntPtr tokenHandle = IntPtr.Zero;

                  // Get the user token for the specified user, domain, and password using the
                  // unmanaged LogonUser method.
                  const int LOGON32_PROVIDER_DEFAULT = 0;
                  //This parameter causes LogonUser to create a primary token.
                  const int LOGON32_LOGON_INTERACTIVE = 2;

                  // Call LogonUser to obtain a handle to an access token.
                  bool returnValue = LogonUser(userName, domainName, password,
                        ref tokenHandle);
                  if (!returnValue)
                        int ret = Marshal.GetLastWin32Error();
                        throw new ApplicationException ("Impersonation logon failed with code " + ret + "\nError: " + GetErrorMessage(ret));
                  // The token that is passed to the following constructor must
                  // be a primary token in order to use it for impersonation.
                  identity = new WindowsIdentity(tokenHandle);
                  WindowsImpersonationContext impersonatedUser = identity.Impersonate();

                  // Free the tokens.
                  if (tokenHandle != IntPtr.Zero)

                  return impersonatedUser;        

------------------------ Now the code that does the work ---------------------------------
WindowsImpersonationContext impersonationContext = null;

      // Impersonate the user
      WindowsIdentity identity;
      impersonationContext = ImpersonationHelper.Impersonate (userDomain, userName, userPassword, out identity);

      // Do the job: check the CPU usage on the remote machine under the credentials of the new user
catch (Exception ex)
      // Do some exception handling, like inform the user that something bad happened
      // De-impersonate
      if (impersonationContext != null)

Author Comment

ID: 13795865
 Thanks for the code. I did it at last. Finally I found the WMI for Win32_Processor and the property "LoadPercentage"(where will u find these properties). It was difficult for me find out the properties available in the Win32_Processor.
But your code is Elaborate and very extensive.  Thanks for ur help. I will take the code of yours and change according to my reuiqment.
Here is my sample code which I tested earlier.
private System.Windows.Forms.Label label1;
            private System.Diagnostics.PerformanceCounter PC;
            public System.Timers.Timer Ticker = new System.Timers.Timer();  
// System.Management Objects
            private ManagementObjectCollection queryCollection = null;
            private ConnectionOptions options = new ConnectionOptions();
            private ManagementObjectSearcher query;
            private System.Management.ObjectQuery oq;
            private ManagementScope scope;
            private WqlObjectQuery objQery;
            private System.Windows.Forms.Label label2;

public Form1()
                  // Required for Windows Form Designer support
                  Ticker.Elapsed += new

                  // TODO: Add any constructor code after InitializeComponent call

private void Ticker_Tick(object sender, System.Timers.ElapsedEventArgs e)
                  //label2.Text = PC.NextValue().ToString() ;
                  //label2.Text =ChkCPU(queryCollection);

private void Form1_Load(object sender, System.EventArgs e)
            private void Perf()
                  Ticker.Interval =1000;
                  //System.Diagnostics.PerformanceCounterPermission pcp= new PerformanceCounterPermission    
                  //System.Diagnostics.PerformanceCounterPermission pcp= new PerformanceCounterPermission(System.Diagnostics.PerformanceCounterPermissionAccess.Administer ,"dev-chen-pc621","Processor");  
                  //PC =  new System.Diagnostics.PerformanceCounter("Processor","% Processor Time" ,"_Total","dev-chen-pc244");//dev-chen-pc621");
                  //label2.Text = PC.NextValue().ToString() ;  

            private void ChkCPU()
                  query = new ManagementObjectSearcher(scope,objQery);
                  queryCollection = query.Get();
                  string sPercentage="";
                  foreach (ManagementObject mo  in queryCollection)
                        sPercentage =mo["LoadPercentage"].ToString();
                  label1.Text =sPercentage;
            private void Test()
                  //ManagementObjectCollection qryCollection;
                  //options.Username = "babura"; //could be in domain\user format
                  //options.Password = "thesys";
                  scope = new ManagementScope("\\\\localhost\\root\\cimv2",options);
                        objQery = new WqlObjectQuery("Select * from Win32_Processor");
                  catch (Exception e)
                        Console.WriteLine("Failed to connect: " + e.Message);


Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question