Как узнать, какой процесс блокирует файл с помощью .NET?

jmap - стандартная утилита java, которую вы можете использовать для сбора дампов и статистики кучи. Я не могу сказать, какой протокол используется jmap для подключения к JVM для получения этой информации, и неясно, доступна ли эта информация для программы, запущенной в JVM напрямую (хотя я уверен, что программа может запросить JVM через некоторый сокет, чтобы получить эту информацию).

JVM TI - это интерфейс инструмента, используемый кодом C, и он имеет довольно полный доступ к событиям JVM, но это код C, а не напрямую доступный JVM. Возможно, вы могли бы написать C lib, а затем интерфейс с ним, но нет ничего из этого.

Существует несколько JMX MBeans, но я не думаю, что любой из них предоставляет фактический счет объекта. Вы можете получить статистику памяти из них (это то, что использует JConsole). Изучите классы java.lang.management.

Если вы хотите быстро (легко реализовать, не обязательно быстрый результат, так как jmap занимает некоторое время), я бы отменил запуск jmap, и просто прочитайте полученный файл.

144
задан Community 23 May 2017 в 10:31
поделиться

4 ответа

Одна из хороших вещей [приблизительно 110] - то, что можно выполнить ее как подпроцесс и проанализировать вывод.

Мы делаем это в нашем сценарии развертывания - работы как очарование.

35
ответ дан orip 23 May 2017 в 10:31
поделиться

Это работает на dlls, заблокированный другими процессами. Эта стандартная программа не узнает, например, что текстовый файл заблокирован wordprocess.

C#:

using System.Management; 
using System.IO;   

static class Module1 
{ 
static internal ArrayList myProcessArray = new ArrayList(); 
private static Process myProcess; 

public static void Main() 
{ 

    string strFile = "c:\\windows\\system32\\msi.dll"; 
    ArrayList a = getFileProcesses(strFile); 
    foreach (Process p in a) { 
        Debug.Print(p.ProcessName); 
    } 
} 


private static ArrayList getFileProcesses(string strFile) 
{ 
    myProcessArray.Clear(); 
    Process[] processes = Process.GetProcesses; 
    int i = 0; 
    for (i = 0; i <= processes.GetUpperBound(0) - 1; i++) { 
        myProcess = processes(i); 
        if (!myProcess.HasExited) { 
            try { 
                ProcessModuleCollection modules = myProcess.Modules; 
                int j = 0; 
                for (j = 0; j <= modules.Count - 1; j++) { 
                    if ((modules.Item(j).FileName.ToLower.CompareTo(strFile.ToLower) == 0)) { 
                        myProcessArray.Add(myProcess); 
                        break; // TODO: might not be correct. Was : Exit For 
                    } 
                } 
            } 
            catch (Exception exception) { 
            } 
            //MsgBox(("Error : " & exception.Message)) 
        } 
    } 
    return myProcessArray; 
} 
} 

VB.Net:

Imports System.Management
Imports System.IO

Module Module1
Friend myProcessArray As New ArrayList
Private myProcess As Process

Sub Main()

    Dim strFile As String = "c:\windows\system32\msi.dll"
    Dim a As ArrayList = getFileProcesses(strFile)
    For Each p As Process In a
        Debug.Print(p.ProcessName)
    Next
End Sub


Private Function getFileProcesses(ByVal strFile As String) As ArrayList
    myProcessArray.Clear()
    Dim processes As Process() = Process.GetProcesses
    Dim i As Integer
    For i = 0 To processes.GetUpperBound(0) - 1
        myProcess = processes(i)
        If Not myProcess.HasExited Then
            Try
                Dim modules As ProcessModuleCollection = myProcess.Modules
                Dim j As Integer
                For j = 0 To modules.Count - 1
                    If (modules.Item(j).FileName.ToLower.CompareTo(strFile.ToLower) = 0) Then
                        myProcessArray.Add(myProcess)
                        Exit For
                    End If
                Next j
            Catch exception As Exception
                'MsgBox(("Error : " & exception.Message))
            End Try
        End If
    Next i
    Return myProcessArray
End Function
End Module
7
ответ дан Stefan 23 May 2017 в 10:31
поделиться
  • 1
    Я фигурировал:) Я только знаю это, потому что я попробовал его однажды и думал мне , я знал этого..., как я делал это, снова? XD – Joseph Marikle 7 August 2011 в 01:12

У меня возникли проблемы с решением Стефана . Ниже приведена измененная версия, которая, кажется, работает хорошо.

using System;
using System.Collections;
using System.Diagnostics;
using System.Management;
using System.IO;

static class Module1
{
    static internal ArrayList myProcessArray = new ArrayList();
    private static Process myProcess;

    public static void Main()
    {
        string strFile = "c:\\windows\\system32\\msi.dll";
        ArrayList a = getFileProcesses(strFile);
        foreach (Process p in a)
        {
            Debug.Print(p.ProcessName);
        }
    }

    private static ArrayList getFileProcesses(string strFile)
    {
        myProcessArray.Clear();
        Process[] processes = Process.GetProcesses();
        int i = 0;
        for (i = 0; i <= processes.GetUpperBound(0) - 1; i++)
        {
            myProcess = processes[i];
            //if (!myProcess.HasExited) //This will cause an "Access is denied" error
            if (myProcess.Threads.Count > 0)
            {
                try
                {
                    ProcessModuleCollection modules = myProcess.Modules;
                    int j = 0;
                    for (j = 0; j <= modules.Count - 1; j++)
                    {
                        if ((modules[j].FileName.ToLower().CompareTo(strFile.ToLower()) == 0))
                        {
                            myProcessArray.Add(myProcess);
                            break;
                            // TODO: might not be correct. Was : Exit For
                        }
                    }
                }
                catch (Exception exception)
                {
                    //MsgBox(("Error : " & exception.Message)) 
                }
            }
        }

        return myProcessArray;
    }
}

ОБНОВЛЕНИЕ

Если вы просто хотите знать, какие процессы блокируют конкретную DLL, вы можете выполнить и проанализировать вывод tasklist / m YourDllName .dll . Работает на Windows XP и новее. См.

Что это делает? tasklist / m "mscor *"

10
ответ дан 23 November 2019 в 22:31
поделиться

Вызвать Win32 из C # очень сложно.

Вы должны использовать инструмент Handle.exe .

После этого ваш код C # должен быть следующее:

string fileName = @"c:\aaa.doc";//Path to locked file

Process tool = new Process();
tool.StartInfo.FileName = "handle.exe";
tool.StartInfo.Arguments = fileName+" /accepteula";
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();           
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();

string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
foreach(Match match in Regex.Matches(outputTool, matchPattern))
{
    Process.GetProcessById(int.Parse(match.Value)).Kill();
}
60
ответ дан 23 November 2019 в 22:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: