Как получить список открытых дескрипторов файлов по процессу на С#?
Как получить список открытых дескрипторов файлов по идентификатору процесса в С#?
Я заинтересован в том, чтобы копать и получать имена файлов.
Ищете программный эквивалент того, что делает проводник процессов.
Скорее всего, это потребует взаимодействия.
Учитывая добавление щедрости к этому, реализация довольно неприятна.
Ответы
Ответ 1
Это будет сложно сделать из управляемого кода.
Существует пример в кодепроекте
Большинство вещей можно сделать в interop, но вам нужен драйвер, чтобы получить имя файла, потому что он живет в адресном пространстве ядра. Process explorer вставляет драйвер в свои ресурсы. Получение этой цели связано с С# и поддержкой 64 бит, а также 32, будет серьезной головной болью.
Ответ 2
Вы также можете запустить приложение командной строки, Handle, Марк Русинович, и проанализировать вывод.
Ответ 3
Вы можете P/INVOKE в функцию NtQuerySystemInformation
запросить все дескрипторы, а затем перейти оттуда. Этот обсуждение групп Google содержит сведения.
Ответ 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;
}