Не будет способа найти процесс, который открыл файл, не заходя в WinApi, я не думаю.А что касается проверки того, используется ли он, единственное, что вы действительно можете сделать, так как вопросы SO, которые вы связали с состоянием, - это обернуть попытки доступа к файлу в блок try / catch.
Код, позволяющий определить, какой файл был открыт, вероятно, будет уродливым, но, возможно, существует API-интерфейс, который хорошо оборачивает это.Есть сторонние утилиты, которые скажут вам об этом ( Unlocker является наиболее известным примером).Вы также можете использовать ProcessExplorer для поиска открытых дескрипторов файлов по имени файла.Это не очень помогает вам, хотя.
Короткий ответ на то, что я пытаюсь донести до вас, состоит в том, что у вас есть ответ на первую часть вашего вопроса в SO-вопросах, которые вы уже связали, а вторая часть, вероятно, потребует вызовов WIN32, которыевы хотите избежать, но вам, вероятно, придется испачкать руки в Win32 ... Все еще хотите помочь?
РЕДАКТИРОВАТЬ: Вы могли бы раскошелиться на утилиту sysinternals Handle .Вам нужно будет получить выходные данные этой команды и проанализировать ее самостоятельно.Вы можете прочитать вывод выполненного процесса следующим образом:
string result = proc.StandardOutput.ReadToEnd();
Проблема в том, что вы получите всплывающее окно с лицензионным соглашением при первом запуске утилиты Handle.Не говоря уже о проблемах лицензирования, если вы планируете развернуть это ...
Если вы все еще заинтересованы, я могу показать вам, как вы поступите с этим.
РЕДАКТИРОВАТЬВот исполняемая программа, которая найдет exe-имя и pid любой программы, имеющей открытый дескриптор файла.Я добавил комментарии, но могу уточнить дальше при необходимости.Я использую Регулярные выражения здесь, чтобы проанализировать вывод, так как это наиболее целесообразно с учетом поставленной задачи.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ProcessStartInfo si = new ProcessStartInfo();
si.FileName = "handle.exe"; //name of the handle program from sysinternals
//assumes that its in the exe directory or in your path
//environment variable
//the following three lines are required to be able to read the output (StandardOutput)
//and hide the exe window.
si.RedirectStandardOutput = true;
si.WindowStyle = ProcessWindowStyle.Hidden;
si.UseShellExecute = false;
si.Arguments = "test.xlsx"; //this is the file you're trying to access that is locked
//these 4 lines create a process object, start it, then read the output to
//a new string variable "s"
Process p = new Process();
p.StartInfo = si;
p.Start();
string s = p.StandardOutput.ReadToEnd();
//this will use regular expressions to search the output for process name
//and print it out to the console window
string regex = @"^\w*\.EXE";
MatchCollection matches = Regex.Matches(s, regex, RegexOptions.Multiline);
foreach (var match in matches)
{
Console.WriteLine(match);
}
//this will use regex to search the output for the process id (pid)
//and print it to the console window.
regex = @"pid: (?<pid>[0-9]*)";
matches = Regex.Matches(s, regex, RegexOptions.Multiline);
foreach (var obj in matches)
{
Match match = (Match)obj; //i have to cast to a Match object
//to be able to get the named group out
Console.WriteLine(match.Groups["pid"].Value.ToString());
}
Console.Read();
}
}
}