Как получить список открытых дескрипторов файлов по процессу на С#?

Как получить список открытых дескрипторов файлов по идентификатору процесса в С#?

Я заинтересован в том, чтобы копать и получать имена файлов.

Ищете программный эквивалент того, что делает проводник процессов.

Скорее всего, это потребует взаимодействия.

Учитывая добавление щедрости к этому, реализация довольно неприятна.

Ответ 1

Это будет сложно сделать из управляемого кода.

Существует пример в кодепроекте

Большинство вещей можно сделать в interop, но вам нужен драйвер, чтобы получить имя файла, потому что он живет в адресном пространстве ядра. Process explorer вставляет драйвер в свои ресурсы. Получение этой цели связано с С# и поддержкой 64 бит, а также 32, будет серьезной головной болью.

Ответ 2

Вы также можете запустить приложение командной строки, Handle, Марк Русинович, и проанализировать вывод.

Ответ 4

Посмотрите этот файл: 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

Ответ 5

Handle - отличная программа, и ссылка на codeproject хороша.

@Брайан Причиной этого кода является то, что handle.exe НЕ РАСПРОСТРАНЯЕТСЯ. Они также не выпускают свой источник.

Похоже, что .Net не будет легко делать это, так как кажется, что для доступа к информации требуется встроенный накопитель. Это невозможно сделать в .net без неиспользуемой DLL. Это относительный глубокий код ядра по сравнению с типичным кодированием .net. Я удивлен, что WMI не раскрывает этого.

Ответ 6

Возможно, используя инструмент командной строки:

OpenedFilesView v1.50 - просмотр открытых/заблокированных файлов в вашей системе (проблемы с нарушениями доступа)

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

Ответ 7

Взгляните на wj32 Process Hacker version 1, который может делать то, что вы просили, и многое другое.

Ответ 8

Чтобы проверить, используется ли какой-либо файл (открыть), используйте File Stream.

Например:

Предположим, что у вас есть путь к файлу, хранящийся в txtAttachPath.Text, и вы хотите открыть этот файл, если он еще не открыт, вам нужно проверить, открыт ли файл, а затем открыть его, вот как это сделать:

создать метод проверки, открыт ли файл:

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 (файл не используется).

Далее, используя метод, инициируемый любым выбранным вами событием:

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, другое решение для него определить, запущен ли процесс.

вам нужно будет добавить еще один метод проверки запуска процесса, связанного с типом файла, который вы пытаетесь открыть:

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;
        }