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.
FOR EACH oProc IN arr
To create the .NET project:
Start Visual Studio 2003Choose File->New->ProjectChoose 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.vbAdd this line at the top:
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
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.WorkingSet = oProc.WorkingSet
redim preserve aResult(nCnt)
aResult(nCnt) = oLMProc ' add it to the array
Catch ex As Exception
' Idle, System processes throw exception "Unable to enumerate the process modules."
debug.WriteLine("Exception " + ex.Message+" "+oProc.ProcessName)
public class LMproc
public ProcessName as String
public ID as Integer
public WorkingSet as Integer
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
CREATE CURSOR results (id i, WorkingSet i,Name c(20))
FOR EACH oproc IN arr
INSERT INTO results VALUES (oProc.id,oProc.WorkingSet,oProc.ProcessName)
SELECT * FROM results ORDER BY WorkingSet descending,name
Please let me know how you expand on this example.