43

How do I get the list of open file handles by process id in C#?

I'm interested in digging down and getting the file names as well.

Looking for the programmatic equivalent of what process explorer does.

Most likely this will require interop.

Considering adding a bounty on this, the implementation is nasty complicated.

Sam Saffron
  • 128,308
  • 78
  • 326
  • 506
  • 3
    To those who stumble upon this thread, the answer proposed by @manuc66 ended up working for me. BUT, the available implementation [here](https://github.com/gjniewenhuijse/MceController/blob/master/VmcServices/DetectOpenFiles.cs) is targeting x86 platform. I have forked the repo and made some adjustment so it can work on both x86 and x64. You can find the modified implementation here: [https://github.com/urosjovanovic/MceController/blob/master/VmcServices/DetectOpenFiles.cs](https://github.com/urosjovanovic/MceController/blob/master/VmcServices/DetectOpenFiles.cs) – urosjovanovic Sep 06 '20 at 19:15

7 Answers7

25

Ouch this is going to be hard to do from managed code.

There is a sample on codeproject

Most of the stuff can be done in interop, but you need a driver to get the filename cause it lives in the kernel's address space. Process Explorer embeds the driver in its resources. Getting this all hooked up from C# and supporting 64bit as well as 32, is going to be a major headache.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Sam Saffron
  • 128,308
  • 78
  • 326
  • 506
  • 1
    Who cares about the code, that thing is useful! Even nicer than Process Explorer, for what it does. – Brian Oct 23 '08 at 17:39
  • this is not something that is easy in managed code, I would probably simply shell out to a c++ program if I had to build something like this @Kiquenet – Sam Saffron Aug 11 '12 at 12:53
12

You can also run the command line app, Handle, by Mark Rusinovich, and parse the output.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
12

Have a look at this file : http://vmccontroller.codeplex.com/SourceControl/changeset/view/47386#195318

And use:

DetectOpenFiles.GetOpenFilesEnumerator(processID);

Demo:

using System;
using System.Diagnostics;

namespace OpenFiles
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var openFiles = VmcController.Services.DetectOpenFiles.GetOpenFilesEnumerator(Process.GetCurrentProcess().Id))
            {
                while (openFiles.MoveNext())
                {
                    Console.WriteLine(openFiles.Current);
                }
            }
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

It has dependency over assembly System.EnterpriseServices

manuc66
  • 2,701
  • 29
  • 28
  • Running it like you mentioned GetOpenFilesEnumerator returns an object with 2 members:
    ERROR_ACCESS_DENIED and ERROR_INVALID_PARAMETERS
    – Lucian Sep 11 '14 at 11:08
  • Just tested and this code works fine. maybe you actually don't have the access. – Mehran Oct 15 '15 at 08:56
  • Any idea what assembly is required for "EventTrackingEnabledAttribute" or "ServicedComponent"? – JustBeingHelpful Jan 15 '16 at 21:15
  • 1
    @MacGyver System.EneterpriseServices – dwkd Mar 18 '16 at 15:59
  • VmcController is no longer in System.EnterpriseServices and I could not get this to compile. I needed to include this file https://github.com/gjniewenhuijse/MceController/blob/master/VmcServices/DetectOpenFiles.cs. Thanks to Gert-Jan Niewenhuijse, This apparently started as a side project for Microsoft Visual Media Controoer. I'm using it to shut don office files kept open after they are closed but not forgotten. – dr d b karron Jul 07 '19 at 18:33
  • It produces always an overflow exception – daniol Aug 25 '21 at 11:28
11

You can P/INVOKE into the NtQuerySystemInformation function to query for all handles and then go from there. This Google groups discussion has details.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
2

Handle is great program, and the link to codeproject is good.

@Brian The reason for the code is that handle.exe is NOT redistributable. Nor do they release their source.

It looks as if .Net will not easily do this since it appears that an embedded device drive is requried to access the information. This cannot be done in .net without an unmanged DLL. It's relatviely deep kernel code when compared to typical .net coding. I'm surprised that WMI does not expose this.

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
mkm
  • 29
  • 1
2

Take a look at wj32's Process Hacker version 1, which can do what you asked, and more.

user541686
  • 205,094
  • 128
  • 528
  • 886
1

Perhaps using command line tool:

OpenedFilesView v1.50 - View opened/locked files in your system (sharing violation issues)

http://www.nirsoft.net/utils/opened_files_view.html

Kiquenet
  • 14,494
  • 35
  • 148
  • 243