Fig.1 ProcMonitor 1.0.0.1
Fig.2 ProcMonitor 1.0.0.0
Introduction
With ProcMonitor it is possible to view the processes running under the current user with details such as,
- What Modules(DLL's) are attached,
- How many handles and threads are running,
- Process version,
- etc.
Changes in new version
This is an upgrade to ProcMonitor 1.0.0.0. In this new version, I have added a notifyIcon
, added an icon to the list view, added a table layout and panels for controlling the positioning and layout.
Using the code
The application is compiled using Visual Studio 2008 Team System. As a result, it cannot compile/run under any previous version of Visual Studio, however you can copy the code or use the existing files in earlier versions of Visual Studio. Following is a listing of the source code:
Namespaces used in the application.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
In the code below, I declare a ListView
in the formMain
class and keep all running processes in a Process
array Process[]
.
namespace ProcMonitor
{
public partial class formMain : Form
{
public ListViewItem item1;
public Process[] proc = Process.GetProcesses();
Below are the btnExit_Click
, btnAboutUs_Click
(very simple) and formMain_Load
events. In the formMain_Load
event the function EnumerateProcess()
is called. In this function the Process
class is used which is in the System.Diagnostics
namespace. The EnumerateProcess()
function enumerates all running process in the current user session and stores it in an array of Process
, i.e. proc[]
.
public formMain()
{
InitializeComponent();
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnAboutUs_Click(object sender, EventArgs e)
{
AboutBox frmAbout = new AboutBox();
frmAbout.Show();
}
private void formMain_Load(object sender, EventArgs e)
{
try
{
EnumerateProcess();
}
catch(Exception ex)
{
Throw ex;
}
}
The following code is used to sort the ListView
in ascending and descending order.
private void listViewProcess_ColumnClick(object sender, ColumnClickEventArgs e)
{
if (listViewProcess.Sorting == SortOrder.Ascending)
{
listViewProcess.Sorting = SortOrder.Descending;
}
else
listViewProcess.Sorting = SortOrder.Ascending;
}
Finally, the code shown below is heart of application that displays the details for a process, such as modules, version, memory usage, handle count, thread count, etc. To retrieve the modules and related information the ProcessModuleCollection
class is used.
private void listViewProcess_Click(object sender, EventArgs e)
{
if (listViewProcess.SelectedItems.Count != 0)
{
try
{
string Selected_Process = listViewProcess.SelectedItems[0].Text;
Process[] ObjModulesList = Process.GetProcessesByName(Selected_Process);
ProcessModuleCollection ObjModules = ObjModulesList[0].Modules;
labelProcessName.Text = ObjModulesList[0].MainModule.ModuleName.ToString();
labelProcessID.Text = ObjModulesList[0].Id.ToString();
labelThreads.Text = ObjModulesList[0].Threads.Count.ToString();
labelPriority.Text = ObjModulesList[0].PriorityClass.ToString();
labelProcessDescription.Text =
ObjModulesList[0].MainModule.FileVersionInfo.FileDescription.ToString();
labelMemoryUsage.Text =
((ObjModulesList[0].WorkingSet64) / 1024).ToString();
labelHandles.Text = ObjModulesList[0].HandleCount.ToString();
labelPath.Text = ObjModulesList[0].MainModule.FileName.ToString();
labelProcessVersion.Text =
ObjModulesList[0].MainModule.FileVersionInfo.FileVersion.ToString();
listViewModules.Items.Clear();
foreach (ProcessModule objModule in ObjModules)
{
item1 = new ListViewItem(objModule.ModuleName);
item1.SubItems.Add(objModule.FileName);
item1.SubItems.Add(objModule.FileVersionInfo.CompanyName);
item1.SubItems.Add(objModule.FileVersionInfo.FileVersion.ToString());
item1.SubItems.Add(objModule.FileVersionInfo.FileDescription.ToString());
listViewModules.Items.AddRange(new ListViewItem[] { item1 });
}
labelTotalModulesAttached.Text = ObjModules.Count.ToString();
}
catch (SystemException SysEX)
{
MessageBox.Show("Error: While reading the process, the following error"
"occured.\n"+SysEX.Message,
"Exception",MessageBoxButtons.OK,MessageBoxIcon.Error);
labelProcessName.Text = string.Empty;
labelProcessID.Text = string.Empty;
labelThreads.Text = string.Empty;
labelPriority.Text = string.Empty;
labelProcessDescription.Text = string.Empty;
labelMemoryUsage.Text = string.Empty;
labelHandles.Text = string.Empty;
labelPath.Text = string.Empty;
labelProcessVersion.Text = string.Empty;
labelTotalModulesAttached.Text = string.Empty;
listViewModules.Items.Clear();
}
}
}
private void listViewModules_ColumnClick(object sender, ColumnClickEventArgs e)
{
if (listViewModules.Sorting == SortOrder.Ascending)
{
listViewModules.Sorting = SortOrder.Descending;
}
else
listViewModules.Sorting = SortOrder.Ascending;
}
private void btnRefresh_Click(object sender, EventArgs e)
{
try
{
EnumerateProcess();
}
catch(Exception ex)
{
Throw ex;
}
}
public void EnumerateProcess()
{
listViewProcess.Items.Clear();
foreach (Process pr in proc)
{
pr.Refresh();
if (pr.BasePriority <13)
{
if (pr.SessionId == 1)
{
item1 = new ListViewItem(pr.ProcessName);
item1.SubItems.Add(pr.Id.ToString());
item1.SubItems.Add(((pr.WorkingSet64) / 1024).ToString());
item1.SubItems.Add(pr.MainModule.FileVersionInfo.FileDescription.ToString());
listViewProcess.Items.AddRange(new ListViewItem[] { item1 });
}
}
}
}
}
}
Points of Interest
This program was developed with Visual Studio 2008 on Windows Vista. Vista does not allow accessing other user's sessions and does not allow a low priority process to access a higher priority process, but during development sometimes an application shows that it is running with high priority but still allows the process monitor to access its details, without running under admin
privilege. This seems strange?????