Click here to Skip to main content
15,891,204 members
Articles / Desktop Programming / Win32

Process and Module Viewer

Rate me:
Please Sign up or sign in to vote.
2.85/5 (10 votes)
2 Nov 2010GPL32 min read 61.6K   1.4K   21   32
Displays process details and modules attached .

screenshot_a.png
Fig.1 ProcMonitor 1.0.0.1

screen_a.png
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; /* ListView to display the process */
        public Process[] proc = Process.GetProcesses(); // retrieving all running process

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?????

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Web Developer MFSI
India India
Holds MSc Information Science from BIT Mesra. Area of interest is C# and VB.Net. He loves C# and is involved in Web and Windows Development.

Area of expertise is ASP.Net, C#, AJAX, Java/Vb Script, Sql, XHTML, CSS, UI Design.

In leisure he loves hanging out with friends and pranking on them too

Comments and Discussions

 
GeneralThank you. Pin
Attacktive27-May-15 22:08
Attacktive27-May-15 22:08 
QuestionWPF version Pin
kiquenet.com27-Sep-12 0:29
professionalkiquenet.com27-Sep-12 0:29 
AnswerRe: WPF version Pin
Amit Ranjan1-Oct-12 3:07
Amit Ranjan1-Oct-12 3:07 
GeneralPlease support us older folks.... Pin
Vaclav_21-Jan-11 7:02
Vaclav_21-Jan-11 7:02 
GeneralRe: Please support us older folks.... Pin
Amit Ranjan11-Apr-12 10:26
Amit Ranjan11-Apr-12 10:26 
Generalnice - have 5 Pin
Pranay Rana17-Jan-11 1:18
professionalPranay Rana17-Jan-11 1:18 
GeneralRe: nice - have 5 Pin
Amit Ranjan11-Apr-12 10:28
Amit Ranjan11-Apr-12 10:28 
GeneralRe: nice - have 5 Pin
Pranay Rana15-Apr-12 17:33
professionalPranay Rana15-Apr-12 17:33 
GeneralEmpty catch blocks. Pin
Pete O'Hanlon17-May-08 8:56
mvePete O'Hanlon17-May-08 8:56 
GeneralRe: Empty catch blocks. Pin
Amit Ranjan17-May-08 9:03
Amit Ranjan17-May-08 9:03 
GeneralRe: Empty catch blocks. Pin
Pete O'Hanlon17-May-08 12:06
mvePete O'Hanlon17-May-08 12:06 
GeneralRe: Empty catch blocks. Pin
nbr20-May-08 3:31
nbr20-May-08 3:31 
GeneralRe: Empty catch blocks. Pin
Pete O'Hanlon20-May-08 11:09
mvePete O'Hanlon20-May-08 11:09 
GeneralRe: Empty catch blocks. Pin
johannesnestler2-Nov-10 22:48
johannesnestler2-Nov-10 22:48 
JokeRe: Empty catch blocks. Pin
PIEBALDconsult17-May-08 9:11
mvePIEBALDconsult17-May-08 9:11 
GeneralRe: Empty catch blocks. Pin
#realJSOP17-May-08 9:23
mve#realJSOP17-May-08 9:23 
GeneralRe: Empty catch blocks. Pin
Amit Ranjan17-May-08 10:12
Amit Ranjan17-May-08 10:12 
GeneralRe: Empty catch blocks. Pin
PIEBALDconsult17-May-08 11:10
mvePIEBALDconsult17-May-08 11:10 
GeneralRe: Empty catch blocks. Pin
#realJSOP18-May-08 2:11
mve#realJSOP18-May-08 2:11 
Actually, not all the time. For instance, we have a service that has a file system watcher. This watcher waits for a file to be created, and when it detects one, it fires off a thread, and goes back to watching for more new files.

This thread's first order of business is to wait for the file to finish being written. Instead of using a second file watcher we have a function called WaitForFileAccess(string filename, int timeout), which performs the following functionality:

int timeSpent = 0;
FileStream stream = null;
bool fileReady = false;
do
{
    try
    {
        stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None);
        fileReady = true;
    }
    catch (Exception ex)
    {
        if (ex != null) {}
        Thread.Sleep(500);
        if (timeout > 0)
        {
            timeSpent += 500;
        }
    }
    finally
    {
        if (stream != null)
        {
            stream.Close();
        }
    }
} while (timeSpent < timeout && !fileReady);

if (!fileReady)
{
    // handle the fact that the timeout expired - in our case, we send 
    // an email notifying the interested party that there's been a 
    // problem in the service.
}


As you can see, this is a perfect example of code that appropriately eats an exception. Keep in mind that I'm not saying that it's not good practice to handle every exception - I'm just saying that there are times when you don't want/need to.


"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001


GeneralRe: Empty catch blocks. Pin
Pete O'Hanlon18-May-08 2:15
mvePete O'Hanlon18-May-08 2:15 
GeneralRe: Empty catch blocks. Pin
PIEBALDconsult18-May-08 4:18
mvePIEBALDconsult18-May-08 4:18 
GeneralRe: Empty catch blocks. Pin
Leo Davidson18-May-08 5:31
Leo Davidson18-May-08 5:31 
GeneralRe: Empty catch blocks. Pin
#realJSOP18-May-08 6:01
mve#realJSOP18-May-08 6:01 
GeneralRe: Empty catch blocks. Pin
Leo Davidson18-May-08 7:27
Leo Davidson18-May-08 7:27 
GeneralRe: Empty catch blocks. Pin
Marc Clifton18-May-08 15:30
mvaMarc Clifton18-May-08 15:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.