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

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

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

寻找程序浏览器的程序化等价物。

这很可能需要互操作。

考虑到增加一个赏金,这个实现是非常复杂的。

哎呀,这将是很难做到托pipe代码。

代码项目上有一个示例

大部分的东西都可以在interop中完成,但是你需要一个驱动程序来获取文件名,因为它存在于内核的地址空间中。 进程pipe理器将驱动程序embedded其资源中。 把这一切都从C#连接起来,并支持64位和32位,这将是一个令人头疼的问题。

您也可以通过Mark Rusinovich运行命令行应用程序Handle ,并parsing输出。

您可以将P / INVOKE纳入NtQuerySystemInformation函数来查询所有句柄,然后从那里开始。 这个Google小组讨论有详细信息。

看看这个文件: 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

句柄是一个伟大的程序,并且代码项目的链接是好的。

@Brian代码的原因是,handle.exe不是可再发行的。 他们也不公开他们的来源。

看起来似乎.Net不会轻易做到这一点,因为看起来embedded式设备驱动器需要访问信息。 这不能在没有unmanged DLL的.net中完成。 与典型的.net编码相比,它是相当深的内核代码。 我很惊讶,WMI不公开这个。

也许使用命令行工具:

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

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

看看wj32的Process Hacker版本1 ,它可以做你所要求的,等等。

要检查是否有任何文件正在使用(打开)使用File Stream

例如:

假设你有一个存储在txtAttachPath.Text的文件path,并且你想打开该文件,如果它还没有打开,你需要检查文件是否先打开然后打开它,这是如何做到的:

创build一个方法来检查文件是否打开:

 private bool attachedFileIsOpen(FileInfo file) { FileStream fs = null; try { fs = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (IOException ioe) { MessageBox.Show("The attachment file is already open!, can't open more than once!", "AMP Warning", MessageBoxButtons.OK, MessageBoxIcon.Information); return true; } finally { if (fs != null) fs.Close(); } return false; } 

该方法将检查文件是否打开,并向用户发送消息,指出文件打开,否则返回false(文件未被使用)。

接下来使用您select的任何事件触发的方法:

 FileInfo filePath = new FileInfo(txtAttachPath.Text); if (!txtAttachPath.Text.Equals("No Attachment") && attachedFileIsOpen(filePath) == false && processIsRunning("notepad") == false) { Process openFilebyExtension = Process.Start(txtAttachPath.Text); openFilebyExtension.WaitForInputIdle(); NativeWindow.FromHandle(this.Handle); } 

注意一些像记事本这样的内置Windows程序允许打开同一文件的多个实例,因此无法通过File Stream方法检测到,另一个解决scheme是检测进程是否正在运行。

您将需要添加另一种方法来检查与您尝试打开的文件types关联的正在运行的进程:

 private bool processIsRunning(string process) { Process[] runningProcesses = Process.GetProcessesByName(process); bool processIsRunning = false; if(runningProcesses.Length == 0) { processIsRunning = false; } else { processIsRunning = true; MessageBox.Show("The attachment file is already open!, can't open more than once!", "AMP Warning", MessageBoxButtons.OK, MessageBoxIcon.Information); } return processIsRunning; }