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

Posted on 2005-04-13
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
    LVL 20

    Expert Comment

    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
    I would suggest WMI:

    Such as here:

    Performance Management in Windows (WMIC section).

    LVL 96

    Expert Comment

    by:Bob Learned
    LVL 96

    Expert Comment

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

    LVL 2

    Author Comment

    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

    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.
    LVL 2

    Author Comment

     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

    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

    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:
          /// </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)
    LVL 2

    Author Comment

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


    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Article by: Najam
    Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
    This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
    how to add IIS SMTP to handle application/Scanner relays into office 365.
    Sending a Secure fax is easy with eFax Corporate ( First, Just open a new email message.  In the To field, type your recipient's fax number You can even send a secure international fax — just include t…

    760 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

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now