Welcome to MSDN Blogs Sign in | Join | Help

Write your own Task Manager

Often an error message occurs:

“The process cannot access the file because it is being used by another process.”

Typically it occurs when you try to copy or rebuild the file.
How do you determine which process is using it? One way to release the file may be to reboot. What a pain!
Here’s an easier way to find which process is using it. The .NET framework has some very simple classes that can enumerate the processes running on your machine. We can access these from VFP by COM interop.

Here’s some fox code to determine which processes have, for example, “kernel32.dll” loaded.

x=NEWOBJECT("loadedmodule.loadedmodule")

arr=x.LoadedModule("kernel32.dll")

FOR EACH oProc IN arr

      IF !ISNULL(oproc)

            ?oProc.id,oProc.ProcessName

      ENDIF

ENDFOR

To create the .NET project:

Start Visual Studio 2003
Choose File->New->Project
Choose Visual Basic Projects, ClassLibrary project, Call it “LoadedModule”
It creates a project with a Class1.vb file. Delete that file from the Solution explorer.
Choose Project->Add User Control->COM Class. Name it LoadedModule.vb
Add this line at the top:

imports System.Diagnostics.Debug

Paste this code just before the “End Class”

public function LoadedModule(ModuleName as String) as LMproc()

        Dim oProc As Diagnostics.Process

        dim aResult(0) as LMproc

        dim nCnt as Integer=0

        For Each oProc In Process.GetProcesses()    ' Each running process

            Try

                For Each omod As Diagnostics.ProcessModule In oProc.Modules()   ' Each DLL/EXE loaded in the process

                    If omod.ModuleName.ToString().ToLower() = ModuleName.ToLower Then

                        dim oLMProc as LMproc= new LMproc   ' create a new instance

                        oLMproc.ID =oProc.Id

                        oLMproc.ProcessName=oProc.ProcessName

                        oLMproc.WorkingSet = oProc.WorkingSet

                        redim preserve aResult(nCnt)

                        aResult(nCnt) = oLMProc ' add it to the array

                        nCnt=nCnt+1

                    End If

                Next

           Catch ex As Exception

                ' Idle, System processes throw exception "Unable to enumerate the process modules."

                debug.WriteLine("Exception " + ex.Message+" "+oProc.ProcessName)  

          End Try

        Next

        return aResult

End Function

 

public class LMproc

    public ProcessName as String

    public ID as Integer

    public WorkingSet as Integer

End Class


Then choose Build->Build Solution and run the VFP code above.

The GetProcesses() static method of the Process class.returns an array of all the currently running processes on the machine. The Modules property returns the modules loaded for that particular process. If the module.ModuleName matches the passed in parameter, then a new array element is created for that Process class The LoadedModule method returns that array.

The Process class has lots of useful members. You can add things like memory usage values and processor time to the LoadedModuleObject class as properties and to the array elements and then access them from VFP. You can close a process or even kill it.

You can add a method to return information about a particular process using the GetProcessById method There are lots of other goodies available from the Process class: check it out!

I’ve added WorkingSet (physical memory currently used by process) for this example to see which process is using the most memory

x=NEWOBJECT("loadedmodule.loadedmodule")

arr=x.LoadedModule("kernel32.dll")

CREATE CURSOR results (id i, WorkingSet i,Name c(20))

FOR EACH oproc IN arr

      IF !ISNULL(oproc)

            ?oProc.id,oProc.WorkingSet,oProc.ProcessName

            INSERT INTO results VALUES (oProc.id,oProc.WorkingSet,oProc.ProcessName)

      ENDIF

ENDFOR

SELECT * FROM results ORDER BY WorkingSet descending,name

Please let me know how you expand on this example.

64528

Published Thursday, June 02, 2005 7:02 PM by Calvin_Hsia

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Write your own Task Manager

Thursday, June 02, 2005 9:35 PM by Brian Duff
Is there a way to determine all the file locks a process has? Presumably the code above will only tell you about DLLs a process has loaded.

Sometimes when building my code (particularly when deleting things), applications have locks on files or directories I'm trying to delete. It would be awesome if I could find out who is locking those files (even better if the system error message you get when you try to delete a locked file would tell you who is locking it :))

Brian

# re: Write your own Task Manager

Thursday, June 02, 2005 9:50 PM by Eric Bergman-Terrell
Very cool code snippet, thanks.

# Your Own Task Manager

Thursday, June 02, 2005 10:16 PM by Tech Guru

# Write your own Task Manager

Thursday, June 02, 2005 11:52 PM by Kent Sharkey
You may occasionally need to know all of the apps running on your
machine (and maybe even be able to...

# re: Write your own Task Manager

Sunday, June 05, 2005 10:08 PM by Rick Strahl
There's actually an easier way to do this without Interop using WMI.

lcMachine = ""
lcMoniker = "winmgmts://" + IIF(!EMPTY(lcMachine),lcMachine + "/","")
oWMI = GETOBJECT(lcMoniker)
loProcesses = oWMI.InstancesOf("Win32_Process")

FOR EACH loProcess in loProcesses
? loProcess.ProcessId,loProcess.WorkingSetSize,loProcess.Name
ENDFOR

What's nice here is that it works across the network as well.

Interop is all nice and good when you need it, but if you can avoid it, you definitely should <g>...

Both classes require admin rights to work I believe.

+++ Rick ---

# Shooting yourself in the foot with WMI, Part One - Finding Your Feet

Monday, June 06, 2005 7:53 AM by Stuart Dunkeld

# WMI part one - local queries

Monday, June 06, 2005 3:44 PM by Stuart Dunkeld

# WMI part one - local queries

Monday, June 06, 2005 3:55 PM by Stuart Dunkeld

# re: Write your own Task Manager

Monday, June 06, 2005 6:07 PM by Stuart Dunkeld
Well, I don't know how those automatic links get set up but it made me finish and tidy up my WMI post. The above links are no longer valid.

For the record, this does the same thing as the above program using WMI:

* Objective: show which processes have, for example, “kernel32.dll” loaded.


oWMI = getobject("winmgmts:")
oProcesses = oWMI.ExecQuery("select * from WIN32_Process")

clear

for each oProcess in oProcesses

oFileAssociations = oWMI.ReferencesTo(oProcess.Path_.path, "CIM_ProcessExecutable")
for each oFileAssociation in oFileAssociations
oFile = oWMI.Get(oFileAssociation.Antecedent)
if oFile.FileName = "kernel32" and oFile.Extension = "dll"
? oProcess.name + " has kernel32.dll loaded"
endif
next
next

# WMI part one - local queries

Monday, June 06, 2005 6:07 PM by Stuart Dunkeld

# WMI part one - local queries

Monday, June 06, 2005 6:12 PM by Stuart Dunkeld

# Analyzing Blog hit statistics

Thursday, July 20, 2006 12:54 PM by Calvin Hsia's WebLog
It takes a lot of work to create the blog posts and code samples that I put in my blog, and I was curious...

# Poshol naxui

Friday, May 11, 2007 3:26 PM by oxkbw

http://goodsmarker.s4.bizhat.com <a href= http://goodsmarker.s4.bizhat.com >Goods marker paintball part smart sporting</a> [url=http://goodsmarker.s4.bizhat.com]Goods marker paintball part smart sporting[/url]

# Find which DLLs in your system are rebased

Monday, August 06, 2007 3:48 PM by Calvin Hsia's WebLog

You can use CreateToolhelp32Snapshot and its family of functions to enumerate the running processes on

# re: Write your own Task Manager

Thursday, November 15, 2007 12:14 AM by Kirpal Singh

I appreciate your program. I am working in VB6. I want to kill a process "Depot.exe" from Task Manager using visual basic. How can i do that.

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker