How To Get Process Information Using Diagnostic Classes (TaskManager)
This article is a brief description of what the Diagnostic classes are and how
to use them to dump some information about running processes. I use the tree
view control in my UI so the source code can be a simple example on how to use
one.
The System.Diagnostics namespace, as name suggests, has everything
to do with diagnosing an application. This namespace contains classes to help
with tracing, debugging, performance checking, event logging, thread
information, working with processes, modules, and etc. Since I was trying to
use these classes to dump information about one of my applications, I decided
why not have an application that will show information about all the processes
that are running on a machine. In this version of the application, I am
displaying information about the local machine only. But the utility class
included with this article can be extended to get information about any machine
on the network. The two classes that I have used in the application are System.Diagnostic.Process,
System.Diagnostic.ProcessModule and System.Diagnostic.ProcessThread.
In the next update I will include examples of more Diagnostic classes.
How Do I Get The Name Of Machine
This information is provided by System.Environmentclass's sttaic
property, GetMachineName. It can be used as follows.
System.Environment.MachineName
How Do I Get All Running Processes On A Machine
This information is provided by the static method GetProcesses of
the Process class. This means you do not need an instance of this
object class to use the method. For the local machine you can pass the argument
as “.”.
Process [] m_arrSysProcesses = Process.GetProcesses (".");
Is The Process Responding Or Not
Often we see in the Task Manager that a process is not responding. You can get
this same information by using the Responding property of a
process.
bool bIsResponding = m_Process.Responding;
How Do I Get The Name And ID Of A Process
You can make use of the Id property of a Process to get the ID.
This ID is unique as long as the process is running. If a process dies then the
OS may assign this ID to a newly started process. Conversely, if you know the
unique ID of a process you can use the GetProcessById static
method to get the Process. To get the Name of the process, make use of the ProcessName
property of the Process. The following code is used in the utility class to
extract this information.
m_arrProcNames[i] = m_arrSysProcesses[i].ProcessName;
m_arrIDs[i] = m_arrSysProcesses[i].Id;
bool bResponding = m_arrSysProcesses[i].Responding;
What Are All Modules Loaded By A Process
When a process starts, it loads a bunch of modules/dlls. We can get this list
of loaded modules from the Process instance. You can make use of the Modules
property of the Process class to get an array of all the loaded modules. This
property returns array of ProcessModule objects. The ProcessModule
class has very few properties. You can use this class to get the BaseAddress,
FileVersionInfo, MemorySize, and etc. of a Module.
Process proc = Process.GetProcessById (nProcID);
ProcessModuleCollection modules = proc.Modules;
int nCount = modules.Count;
String [] strNames = null;
if (nCount > 0)
{
strNames = new String[nCount];
nMemSizes = new int[nCount];
for (int i = 0; i < nCount; i++)
{
strNames[i] = modules[i].ModuleName;
nMemSizes[i] = modules[i].ModuleMemorySize;
}
}
How Much Time Has Been Spent By A Process
You can use the StartTime property of a Process to get the time
when the process was started. When a process runs it spends time in the system
core and some in the application portion. The PrivilegedProcessorTime
property is used to get the time a process spends running in the operating
system core. The UserProcessorTime property is used to get the
time a process spends in the application portion.
m_wndStartTime.Text = (proc.StartTime.GetDateTimeFormats('F', DateTimeFormatInfo.InvariantInfo))[0];
m_wndUserTime.Text = proc.UserProcessorTime.ToString ();
m_wndPrevlgProcessorTime.Text = proc.PrivilegedProcessorTime.ToString();
What Priority Is A Process Running At
Every process is assigned a priority by the operating system. This priority can
have one of the following values Idle, Normal, High and Real Time. This
priority information can be obtained from the BasePriority property
of the Process class.
int nPriority = proc.BasePriority;
switch (nPriority)
{
case 8:
m_wndBasePriority.Text = "Normal";
break;
case 13:
m_wndBasePriority.Text = "High";
break;
case 24:
m_wndBasePriority.Text = "Real Time";
break;
case 4:
default:
m_wndBasePriority.Text = "Idle";
break;
}
How Many Threads And Handles Are Associated With A Process
After a process starts, it can start more threads inside the main thread. And
it can also allocates more handles. The number of handles can be obtained by
using the HandleCount property. To get the information about the
threads, use the Threads property. This will return ProcessThreadCollection
object containig all the thread objects. You can use the Id property
of the ProcessThread object to get the unique ID of the thread.
There are bunch of properties and methods exposed by the ProcessThread
class. These can be used to get detailed information about a thread.
int nHandles = proc.HandleCount;
ProcessThreadCollection threads = proc.Threads;
int nThreadID = threads[i].Id;
ThreadPriorityLevel level = threads[i].PriorityLevel;
What Is The Memory Usage By The Process
Process class has some
properties that can be used to get various memory requirements by a process.
Use the properties like VirtualMemorySize, PrivateMemorySize,
PeakVirtualMemorySize, PeakPagedMemorySize, PagedSystemMemorySize,
PagedMemorySize, NonpagedSystemMemorySize, etc.
The names of these properties are very self-explanatory about the purpose they
serve.
m_wndWorkingSet.Text = proc.WorkingSet.ToString();
m_wndMinWorkingSet.Text = proc.MinWorkingSet.ToString();
m_wndNonpagedSysMemory.Text=proc.NonpagedSystemMemorySize.ToString();
m_wndPagedMemory.Text = proc.PagedMemorySize.ToString();
m_wndPagedSysMemory.Text = proc.PagedSystemMemorySize.ToString();
m_wndPeakedPagedMemory.Text = proc.PeakPagedMemorySize.ToString();
m_wndPeakVirtualMemory.Text = proc.PeakVirtualMemorySize.ToString();
m_wndPrivateMemory.Text = proc.PrivateMemorySize.ToString();
m_wndPeakWorkingSet.Text = proc.PeakWorkingSet.ToString();
m_wndVirtualMemory.Text = proc.VirtualMemorySize.ToString();
There Is A Bug In TreeView Control
There is a bug in the TreeView control Click and Double Click
events. The Source object in the event is supposed to return the tree node
corresponding to the tree item clicked. But if you look at the index, it is the
one that you selected previously. I have reported this bug to Microsoft.
Hopefully it will be fixed in the next release. I have not changed the
implementation of this application to use any other control. Keep this in mind
when you look at the information in the detail form. This information
corresponds to the process you selected previously.
The project included with this article is an attempt to replicate the Windows
Task Manager using C# and .NET SDK.