【问题标题】:Get disk usage of a specific process in C#在 C# 中获取特定进程的磁盘使用情况
【发布时间】:2019-05-02 18:54:29
【问题描述】:

如何在 C# 中获取特定进程的磁盘使用率 (MB/s)?

我可以像这样获得 CPU 使用率和 RAM 使用率:

var cpu = new PerformanceCounter("Process", "% Processor Time", ProcessName, true)
var ram = new PerformanceCounter("Process", "Working Set - Private", ProcessName, true);

Console.WriteLine($"CPU = {cpu.NextValue() / Environment.ProcessorCount} %");
Console.WriteLine($"RAM = {ram.NextValue() / 1024 / 1024} MB");

但我找不到与磁盘使用相关的任何内容。

如任务管理器中所示:

【问题讨论】:

  • 在此处查看每个进程的 PerformanceCounters 列表:msdn.microsoft.com/en-us/library/ms804621.aspx 您可能对其中一个或多个与 I/O 相关的内容感兴趣(取决于您究竟需要/想要什么)跨度>
  • 似乎最接近的计数器是“IO Data Bytes/sec”,但它汇总了来自网络、设备和“文件”(磁盘)I/O 的流量。到目前为止,我发现的其他解决方案都太过分了。我会坚持这个。

标签: c# .net


【解决方案1】:

您可以使用DriveInfo

using System;
using System.IO;

class Info {
    public static void Main() {
        DriveInfo[] drives = DriveInfo.GetDrives();
        foreach (DriveInfo drive in drives) {
            //There are more attributes you can use.
            //Check the MSDN link for a complete example.
            Console.WriteLine(drive.Name);
            if (drive.IsReady) Console.WriteLine(drive.TotalSize);
        }
    }
}

【讨论】:

  • 这提供了有关完整驱动器的信息,而不是单个进程的使用情况
  • 对了,我很抱歉。我发现之前的这篇文章有一个可能的解决方案:stackoverflow.com/questions/22021903/…
【解决方案2】:

♻️ 接近

如上所述here^2

此 API 将告诉您 I/O 操作的总数以及总字节数。

您可以调用 GetProcessIoCounters 来获取每个进程的整体磁盘 I/O 数据 - 您需要自己跟踪增量并转换为基于时间的速率。

所以,基于this C# tutorial,您可以按照这些思路做一些事情:

struct IO_COUNTERS
{
    public ulong ReadOperationCount;
    public ulong WriteOperationCount;
    public ulong OtherOperationCount;
    public ulong ReadTransferCount;
    public ulong WriteTransferCount;
    public ulong OtherTransferCount;
}

[DllImport("kernel32.dll")]
private static extern bool GetProcessIoCounters(IntPtr ProcessHandle, out IO_COUNTERS IoCounters);

public static void Main()
{
    IO_COUNTERS counters;
    Process[] processes = Process.GetProcesses();

    foreach(Process process In processes)
    {
        try {
            GetProcessIoCounters(process.Handle, out counters);
            console.WriteLine("\"" + process.ProcessName + " \"" + " process has read " + counters.ReadTransferCount.ToString("N0") + "bytes of data.");
        } catch (System.ComponentModel.Win32Exception ex) {
        }
    }
    console.ReadKey();
}

使用this将其转换为VB.NET

但是(System.ComponentModel.Win32Exception ex)发生

System.ComponentModel.Win32Exception (0x80004005): Access is denied
   at System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
   at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
   at System.Diagnostics.Process.OpenProcessHandle(Int32 access)
   at System.Diagnostics.Process.get_Handle()
   at taskviewerdisktest.Form1.Main() in C:\...\source\repos\taskviewerdisktest\taskviewerdisktest\Form1.vb:line 32

某些进程似乎真的很难访问.. 好消息是,在我的情况下,它们中的数量并不多(250 个中的 15 个或其他)..

⚠️ 免责声明:这更像是一种“解决方案”而不是“解决方案”

♻️ 其他方法和参考

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 2010-11-18
    • 2018-06-30
    • 2016-05-28
    相关资源
    最近更新 更多