如何在 C# 中按进程获取打开文件句柄的列表?

Posted

技术标签:

【中文标题】如何在 C# 中按进程获取打开文件句柄的列表?【英文标题】:How do I get the list of open file handles by process in C#? 【发布时间】:2008-10-07 03:37:24 【问题描述】:

如何在 C# 中按进程 ID 获取打开的文件句柄列表?

我也有兴趣深入挖掘并获取文件名。

寻找进程资源管理器所做的程序化等价物。

这很可能需要互操作。

考虑到为此添加赏金,实现起来非常复杂。

【问题讨论】:

对于那些偶然发现这个线程的人,@manuc66 提出的答案最终对我有用。但是,可用的实现here 是针对 x86 平台的。我已经分叉了 repo 并进行了一些调整,以便它可以在 x86 和 x64 上运行。你可以在这里找到修改后的实现:https://github.com/urosjovanovic/MceController/blob/master/VmcServices/DetectOpenFiles.cs 【参考方案1】:

哎呀,这将很难从托管代码中完成。

有一个sample on codeproject

大部分内容都可以在互操作中完成,但您需要一个驱动程序来获取文件名,因为它位于内核的地址空间中。 Process Explorer 将驱动程序嵌入到其资源中。让这一切都从 C# 连接起来并支持 64 位和 32 位,这将是一个令人头疼的问题。

【讨论】:

谁在乎代码,那东西很有用!就其功能而言,它甚至比 Process Explorer 更好。 这在托管代码中并不容易,如果我必须构建类似 @Kiquenet 的东西,我可能会简单地使用 c++ 程序【参考方案2】:

您还可以运行 Mark Rusinovich 的命令行应用 Handle,并解析输出。

【讨论】:

为什么是@bruce?请问有什么原因吗? 使用句柄的唯一真正问题是许可证 - 你不能分发句柄,即使在免费软件中也是如此。 Handle.exe 是 32 位应用程序,不是吗?因此,您无法从 64 位 C# 应用程序轻松启动它。 还有Handle64.exe还有@seveves【参考方案3】:

看看这个文件: http://vmccontroller.codeplex.com/SourceControl/changeset/view/47386#195318

并使用:

DetectOpenFiles.GetOpenFilesEnumerator(processID);

演示:

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();
        
    

它依赖于程序集System.EnterpriseServices

【讨论】:

像你提到的那样运行 GetOpenFilesEnumerator 返回一个包含 2 个成员的对象:ERROR_ACCESS_DENIED 和 ERROR_INVALID_PARAMETERS 刚刚测试过,这段代码运行良好。也许您实际上没有访问权限。 知道“EventTrackingEnabledAttribute”或“ServicedComponent”需要什么程序集吗? @MacGyver System.EneterpriseServices VmcController 不再在 System.EnterpriseServices 中,我无法编译它。我需要包含这个文件github.com/gjniewenhuijse/MceController/blob/master/VmcServices/…。感谢 Gert-Jan Niewenhuijse,这显然是作为 Microsoft Visual Media Controoer 的一个副项目开始的。我正在使用它来关闭在关闭但不会忘记后保持打开状态的办公室文件。【参考方案4】:

您可以 P/INVOKE 进入 NtQuerySystemInformation 函数以查询所有句柄,然后从那里开始。这个Google groups discussion有详细信息。

【讨论】:

好东西。我会看看我是否可以进行互操作【参考方案5】:

看看 wj32 的Process Hacker version 1,它可以满足你的要求,等等。

【讨论】:

【参考方案6】:

Handle 是一个很棒的程序,codeproject 的链接也很好。

@布莱恩 代码的原因是 handle.exe 不可再分发。他们也没有公布他们的来源。

看起来 .Net 似乎不会轻易做到这一点,因为似乎需要嵌入式设备驱动器才能访问信息。如果没有未管理的 DLL,这无法在 .net 中完成。与典型的 .net 编码相比,它是相对较深的内核代码。我很惊讶 WMI 没有公开这一点。

【讨论】:

【参考方案7】:

也许使用命令行工具:

OpenedFilesView v1.50 - 查看系统中打开/锁定的文件(共享违规问题)

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

【讨论】:

以上是关于如何在 C# 中按进程获取打开文件句柄的列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中按名称获取进程句柄?

如何修改linux单进程能够打开的最大文件句柄数

linux如何获取磁盘的繁忙程度和打开的文件句柄数?

.NET (C#):只有进程句柄或 PID 时获取子窗口?

检查文件是不是被进程文件句柄锁定

vb 获取窗口句柄