locked
CPU usage (in %) for each active process, how is this best determined and implemented in an application? RRS feed

  • Question

  • using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Management;
    using System.ComponentModel;
    using System.Diagnostics;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                GetProcesses();
                Console.Read();
            }
    
            public static void GetProcesses()
            {
                StringBuilder sb = new StringBuilder();
                ManagementClass MgmtClass = new ManagementClass("Win32_Process");
    
                foreach (ManagementObject mo in MgmtClass.GetInstances()) //Goes through each running process and grabs each instance
                    
                  Console.WriteLine("Process:" + mo["Name"] + "  ID:" + mo["ProcessId"] + "   Handles:" + mo["HandleCount"] + "  Threads:" + mo["ThreadCount"]);
                //The above works great
                //I'm having trouble getting the same enumeration for getprocesses to return the memory.
                //foreach (Process p in Process.GetProcesses("."))
                // Console.WriteLine("Memory Allocation:" + p.PrivateMemorySize64.ToString());
    
                Console.WriteLine();
            }
    Hi,

    I'm creating my own version of the task manager with the intent of capturing (snapshot) key performance indicators (memory per process, handles per process etc.)as opposed to constantly monitoring.
    I've researched online and have not found an effective means of accomplishing this.  To add to this, I need to combine the cpu% to the data I collect from WMI and keep in in synch sot he CPU% user for process.foo is accurate.
    If I can get the process ID from both sources of data is there sometype of comparison method that I can use when building the string, something like where processid is = processid.cpu theh cpu is appended to the line of the string.  The code i've come up with (that works ) is attached to give an idea of what I'm trying to accomplish.

    Thank you for looking at my post.
    Profuse thanks
    Monday, January 18, 2010 3:58 AM

Answers

  • Heres a way of doing it using WMI.  Note the commented errors, they have nothing to do with how this code returns process information.
    using System;
    using System.Management;
    using System.Windows.Forms;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.IO;
    
    
    namespace WMISample
    {
        public class MyWMIQuery
        {
            public static void Main()
            {
             
                try
                {
                    
                    ManagementObjectSearcher searcher =
                        new ManagementObjectSearcher("root\\CIMV2",
                        "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");
    
    
                    foreach (ManagementObject queryObj in searcher.Get())
                    {
    
                        StreamWriter SW;
                        SW = File.CreateText("c:\\MyTextFile.txt");//I can't get the StreamWriter to work
    
                        SW.WriteLine("Name: ", queryObj["Name"]);//This fails in that it does not write to the file and I don't understand why
                        Console.WriteLine("ProcessID: {0}", queryObj["IDProcess"]);
                        Console.WriteLine("Handles: {0}", queryObj["HandleCount"]);
                        Console.WriteLine("Threads: {0}", queryObj["ThreadCount"]); 
                        Console.WriteLine("Memory: {0}", queryObj["WorkingSetPrivate"]);
                        Console.WriteLine("CPU%: {0}", queryObj["PercentProcessorTime"]);
                        Console.Read();
                        SW.Close();
                       
                    }
                       
    
                    }
                    catch (ManagementException e)
                    {
                    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
                } 
            }
        }
    }

    Profuse thanks
    • Marked as answer by QA WA Tuesday, January 19, 2010 4:35 AM
    Tuesday, January 19, 2010 4:34 AM

All replies

  • Hello QA WA,

    As to WMI, the CPU usage is not exported directly as a property of Win32_Process, but it can be calculated by some formular. I searched an answer from internet,
    -------------------------------------------------------------------------
    UserTime = ((New_UserModeTime - Old_UserModeTime) / TimeInterval) *
    100;
    KernelTime =(( New_KernelModeTime - Old_KernelModeTime) /
    TimeInterval) * 100;
    CPU = (((New_UserModeTime - Old_UserModeTime) + (New_KernelModeTime -
    Old_KernelModeTime)) / TimeInterval) * 100;
    -------------------------------------------------------------------------

    I paste the link I quote, for your information,
    http://www.eggheadcafe.com/software/aspnet/31073548/cpu-usage-without-perform.aspx

    Otherwise, we'd consider the Performance Counter to get the result. It is wrapped in .NET. See the customer content at the bottom of the article,
    http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecounter.aspx


    Hope this helps and have a nice day!


    Best regards,
    Ji Zhou
    MSDN Subscriber Support in Forum


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Monday, January 18, 2010 9:34 AM
    Moderator
  • Heres a way of doing it using WMI.  Note the commented errors, they have nothing to do with how this code returns process information.
    using System;
    using System.Management;
    using System.Windows.Forms;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.IO;
    
    
    namespace WMISample
    {
        public class MyWMIQuery
        {
            public static void Main()
            {
             
                try
                {
                    
                    ManagementObjectSearcher searcher =
                        new ManagementObjectSearcher("root\\CIMV2",
                        "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");
    
    
                    foreach (ManagementObject queryObj in searcher.Get())
                    {
    
                        StreamWriter SW;
                        SW = File.CreateText("c:\\MyTextFile.txt");//I can't get the StreamWriter to work
    
                        SW.WriteLine("Name: ", queryObj["Name"]);//This fails in that it does not write to the file and I don't understand why
                        Console.WriteLine("ProcessID: {0}", queryObj["IDProcess"]);
                        Console.WriteLine("Handles: {0}", queryObj["HandleCount"]);
                        Console.WriteLine("Threads: {0}", queryObj["ThreadCount"]); 
                        Console.WriteLine("Memory: {0}", queryObj["WorkingSetPrivate"]);
                        Console.WriteLine("CPU%: {0}", queryObj["PercentProcessorTime"]);
                        Console.Read();
                        SW.Close();
                       
                    }
                       
    
                    }
                    catch (ManagementException e)
                    {
                    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
                } 
            }
        }
    }

    Profuse thanks
    • Marked as answer by QA WA Tuesday, January 19, 2010 4:35 AM
    Tuesday, January 19, 2010 4:34 AM