Download source files - 20 Kb
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 the Process class' method GetMachineName
.
You can use this method on the current process. It can be used as follows.
Process.GetCurrentProcess().GetMachineName()
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 “.”. The documentation says that you can pass
an empty string to get processes on local machine but, this is a bug in the documentation and has
been confirmed by Microsoft. The correct way is to pass no argument or “.”, if you want
to get the processes on the local machine.
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);
ProcessModule [] modules = proc.Modules;
int nCount = modules.Length;
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.Format ("F", DateTimeFormatInfo.InvariantInfo);
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 an array of ProcessThread
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;
ProcessThread [] procThreads = proc.Threads;
int nThreadID = procThreads[i].Id;
ThreadPriorityLevel level = procThreads[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();
What Is Left
I have not used all the facilities exposed by the Process
, ProcessModule
and
ProcessThread
classes. This application is still under development. As I go along, I will keep
updating this article as well as the application.
There Is A Bug In TreeView Control
Like all Beta products, bugs exist. 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. They have reviewed it. Hopefully it will be fixed in the next Beta 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. In the next update I will update some performance counters.