🗿

[WPF/C#] WPFで、UWPのAPIを使ってプロセス毎のCPU時間とメモリ使用量をとる

2021/08/06に公開

もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

やりたいこと

UWPのAPIを使って、プロセスの一覧を取得したい。
ついでに、CPU時間、メモリ使用量を取得したい。

やり方

UWPのAPI「ProcessDiagnosticInfoクラス」を使う。

必要nugetライブラリ
Microsoft.Windows.SDK.Contracts
(今回は10.0.19041.1を使用)

サンプルコード

using System;
using System.Linq;
using System.Threading;
using Windows.System.Diagnostics;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            var processes = ProcessDiagnosticInfo.GetForProcesses().Where(x => x.ExecutableFileName.Contains("chrome")).ToList();

            while (true)
            {
                Console.Clear();

                foreach (var p in processes)
                {
                    Console.WriteLine(p.ProcessId + ", " + p.CpuUsage.GetReport().KernelTime + ", " + p.MemoryUsage.GetReport().WorkingSetSizeInBytes + ", " + p.DiskUsage.GetReport().BytesWrittenCount);
                }

                Thread.Sleep(2000);
            }
        }
    }
}

注意

遅い&重い。
1つのプロセスの情報をとるくらいならそれほどでもないが、
数十個のプロセスのCPU時間を見たい、とかをやりだすと、時間がかかるうえに、CPUに負荷がかかる。
(何となく、内部でパフォーマンスカウンタを見るようなことしていて、それが重いのか?と想像)
(パフォーマンスカウンタを使っても、同じくらい重いので→こちら)

重いことに対する代替案

Processクラス

試したところ、ProcessクラスのTotalProcessorTimeとかWorkingSet64をみれば、ProcessDiagnosticInfoよりは早く情報が取れるっぽい。
ただ、それだとディスクの使用量がとれそうなプロパティがない。どこからディスク使用量とればいいのか。。。(ETWか、、、)

WMI?

試してないが、WMIでもCPU使用率、メモリ使用量、ディスク使用量やネットワーク使用量がとれるっぽい。

https://www.it-swarm-ja.com/ja/windows/プロセスごとのcpuおよびメモリ使用量の追跡/957380216/

http://eternalwindows.jp/windevelop/wmi/wmi04.html

WMIを使うためのManagementClassの使い方
https://johobase.com/wmi-win32-operating-system-csharp/

参考

ProcessDiagnosticInfoクラス(MSdocs)
https://docs.microsoft.com/en-us/uwp/api/windows.system.diagnostics.processdiagnosticinfo?view=winrt-20348

Discussion