Посмотрите, какие процессы заблокированы в C#
В старых версиях Windows было невозможно определить, какие процессы заблокировали файл. Система отслеживала количество блокировок в файле, и процессы отвечали за увеличение и уменьшение счета для представления своих собственных блокировок.
Недавно (я думаю, начиная с Windows XP). Windows включила новый диспетчер перезагрузки, чтобы помочь в перезапуске системы во время установки. Чтобы упростить перезагрузку, Windows теперь отслеживает процессы, которые заблокировали файл, и вы можете использовать Restart Manager для чтения этого списка процессов.
У .NET Framework нет каких-либо инструментов для работы с Restart Manager, поэтому вам необходимо использовать его API, и для этого требуются обычные уродливые объявления. Загрузите пример, чтобы увидеть их всех в полной мере.
В следующем коде показан метод FindLockers, который используется в этом примере для получения списка процессов, у которых файл заблокирован.
static public ListFindLockers(string filename) { uint session_handle; string session_key = Guid.NewGuid().ToString(); int result = RmStartSession(out session_handle, 0, session_key); if (result != 0) throw new Exception("Error " + result + " starting a Restart Manager session."); List processes = new List (); try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, num_procs = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { filename }; result = RmRegisterResources( session_handle, (uint)resources.Length, resources, 0, null, 0, null); if (result != 0) throw new Exception("Could not register resource."); result = RmGetList(session_handle, out pnProcInfoNeeded, ref num_procs, null, ref lpdwRebootReasons); if (result == ERROR_MORE_DATA) { RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; num_procs = pnProcInfoNeeded; result = RmGetList(session_handle, out pnProcInfoNeeded, ref num_procs, processInfo, ref lpdwRebootReasons); if (result != 0) throw new Exception("Error " + result + " listing lock processes"); for (int i = 0; i < num_procs; i++) { try { processes.Add( Process.GetProcessById(processInfo[i]. Process.dwProcessId)); } catch (ArgumentException) { } } } else if (result != 0) throw new Exception("Error " + result + " getting the size of the result."); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { RmEndSession(session_handle); } return processes; }
Сначала метод создает новый сеанс диспетчера перезагрузки. Затем он создает пустой список для хранения объектов Process и вводит блок try-catch.
Затем метод вызывает метод RmRegisterResources для регистрации имени файла с помощью Restart Manager. Затем он вызывает метод RmGetList, чтобы узнать, сколько процессов имеет блокировки в файле. Он вызывает RmGetList снова, чтобы получить информацию о процессах. Затем код затем просматривает результаты и использует возвращенные идентификаторы процессов для получения объектов Process, представляющих объекты, у которых файл заблокирован.
Метод завершается возвратом списка объектов Process.
Загрузите пример, чтобы увидеть более подробную информацию. Этот пример был основан на сообщении MSDN,
Чтобы протестировать программу, запустите ее, а затем откройте исполняемый файл в Microsoft Word. (Это будет выглядеть как тарабарщина в Word.) Затем нажмите кнопку «Найти замки» программы. Вы должны увидеть процессы с именем howto_find_file_locker.vshost (Visual Studio, запускающие программу) и WINWORD.
Если вы затем дважды щелкните исполняемый файл, вы можете снова запустить программу. Он и предыдущий экземпляр программы должны перечислять два предыдущих процесса плюс howto_find_file_locker, представляющие новый экземпляр программы.