.net C#中获取特定进程的磁盘使用情况

fae0ux8s  于 2023-06-25  发布在  .NET
关注(0)|答案(3)|浏览(191)

如何在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");

但我找不到任何与磁盘使用有关的信息。
如任务管理器所示:

plicqrtu

plicqrtu1#

️方法

如上所述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个或什么)。

  • 免责声明:**这更像是对“解决方案”而不是“解决方案”的一种说法 *

️其他方法和参考

brccelvz

brccelvz2#

您可以使用GetProcessDiskUsage API来获取进程IO信息,例如写和读操作的数量以及读或写的总字节数。下面的代码显示了进程磁盘使用情况,单位为MB/s,与任务管理器中类似。

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

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

    private static double GetProcessDiskUsage(IntPtr processHandle)
    {

        IO_COUNTERS ioC1 = new IO_COUNTERS();
        GetProcessIoCounters(processHandle, out ioC1);
        double totalBytes1 = (ioC1.ReadTransferCount + ioC1.WriteTransferCount) / 1024f / 1024f;

        int time = 1;
        Thread.Sleep(time * 1000);

        IO_COUNTERS ioC2 = new IO_COUNTERS();
        GetProcessIoCounters(processHandle, out ioC2);
        double totalBytes2 = (ioC2.ReadTransferCount + ioC2.WriteTransferCount) / 1024f / 1024f;

        return (totalBytes2 - totalBytes1) / time;

    }

    static void Main(string[] args)
    {

        Console.WriteLine("Enter the process ID:");

        if (!Int32.TryParse(Console.ReadLine(), out int processId))
        {
            Console.WriteLine("Invalid process ID");
            return;
        }

        Process process = Process.GetProcessById(processId);

        while (true)
        {
            double disk = Math.Round(GetProcessDiskUsage(process.Handle), 2);

            Console.WriteLine($"{process.ProcessName}: {disk} MB/s");

        }

    }
edqdpe6u

edqdpe6u3#

可以使用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);
        }
    }
}

相关问题