[C#/WMI] WMIで何かの値を取りたいときの、どこからとればいいかの調べ方
やりたいこと
今回、Windowsのパフォーマンス情報(具体的には、PC全体のCPU使用率)の値を取りたいなと思い、いろいろその方法を調べていたところ、「WMI」というのを利用すると取れそうということが分かった。
ただその情報をMSのドキュメントで調べようと思っても、なかなかよい情報にたどり着けない。
いろいろさまよっていたところ、なんとなく参考になる情報を取れそうなツールを見つけたので、それを利用して、どこからどういう情報をとれるか調べようと思った。その時のメモ。
wbemtest
Windowsに標準で入ってるっぽいwbemtest
というツールを使う。
(標準ではないかも?開発環境(VisualStudioとか)を入れてるPCにしか入ってない?手元にそうじゃないPCがなかったので未確認)
Ctrl+Rでファイル名を指定して実行を開いてwbemtest
と入力、Entを押す。
下記のツールが立ち上がる。
まず[接続]を押す。
下図のような画面になるので、特になにも変えず(「名前空間」の欄を「root\cimv2」にしたままで)「接続」を押す。
次に[クラスの列挙]を押すと、こういう画面になる。
ここで、[スーパークラス名の入力]欄にはなにも入れず、[再起]にチェックを入れてOKを押すと、
使えそうなクラスの一覧が出てくる。
そこに表示されているクラスの中から、今回はPC全体のCPUの情報が欲しいのでWin32_PerfRawData_PerfProc_Process
を選んだ。
(選んだ理由:ネット情報でそういうのがあると知ったから。そこにたどり着くためには...今はキーワードを変えながらいろいろ検索するしかなかった...)
Win32_PerfRawData_PerfProc_Process
をダブルクリックすると、下記のような画面になる。
上記画面の[プロパティ]の欄が、そこから読み取れる情報(=プロパティ)の一覧。
Win32_PerfRawData_PerfProc_Process
の場合は、そこに並んでいるプロパティはなんとなく「パフォーマンスモニター」に出てくるプロパティの名前に似ている。
パフォーマンスモニターの方なら、下記にチェックを入れると一応説明が出てくれるので、選択の助けになるかもしれない。
今回は、CPU使用率を取りたいので、「PercentProcessorTime」がそれっぽいなと思ったので、その項目を選択する。
選択した状態で、欄の右にある[インスタンス]ボタンを押す。
そうすると、「PercentProcessorTime」で使えるインスタンスの一覧が出てくる。
上記だと、「Name」というプロパティが0,1,2,3、_Total であるという5つのインスタンスがある。
パフォーマンスカウンタだと、_Totalを使えば、0,1,2,3の全部を合わせた値が取れていたので、おそらくここでもそうだと思われる。
つかうものととれるもの
以上をまとめると、
Win32_PerfRawData_PerfProc_Process
クラスの
PercentProcessorTime
プロパティを
_Total
というインスタンスを指定して
取得すれば、PC全体のCPU時間が取れそうと分かった。
※「CPU使用率」という値は取れなくて、「CPU時間」という値が取れるらしい。
CPU時間からCPU使用率に直すやり方はありそうなので、まずはCPU時間を取得する。
C#でそれをとる
C#でそれをとるためのコードは、下記のようになる。
using System;
using System.Management;
using System.Threading;
namespace PerfDataWithWmi
{
class Program
{
// エントリーポイント
static void Main(string[] args)
{
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\cimv2");
ObjectQuery query_total = new ObjectQuery("SELECT * FROM Win32_PerfRawData_PerfOS_Processor WHERE Name=\"_Total\"");
ManagementObjectSearcher searcher_total = new ManagementObjectSearcher(scope, query_total);
ManagementObjectCollection queryCollection = searcher_total.Get();
foreach (ManagementObject m in queryCollection)
{
Console.WriteLine(m["PercentProcessorTime"].ToString());
m.Dispose();
}
}
}
}
クエリの文字列"SELECT * FROM Win32_PerfRawData_PerfOS_Processor WHERE Name=\"_Total\""
の、WHERE
でインスタンスを選別したいけどどうやって選別したらいいか(Nameが何のものを選べばいいか)がわからなかったときに、wbemtest
があることを知って、いろいろいじる中でインスタンスの一覧を見れることを知り、_Totalを取ればいいかな、ということが分かった。
実際、それで動かしてみて、大体正しそうな値が出てるので、それでよいのだと思われる。
(ただ、ほんとにそれでよいのか、という裏が取れそうなMS公式のドキュメントは見つけられていないが...)
※ここまでで、全体の「CPU時間」は取れたが、「CPU使用率」はここからCPU時間を使って計算することが必要。ただ全然難しい計算ではないので、下記をもとに計算すれば算出できる。
C#コードで、ManagementObjectの中の全プロパティを表示させてみたい
取ってきたManagementObjectの中にどんなプロパティがあるかは、wbemtestツールで見てもいいが、C#コードで見るとしたら下記のようにする。
using (ManagementObjectCollection queryCollection = searcher.Get())
{
foreach (ManagementObject m in queryCollection)
{
foreach (PropertyData prop in m.Properties)
{
Console.WriteLine("{0}: {1}", prop.Name, prop.Value);
}
m.Dispose();
}
}
所感
とにかく、WMIを使ってCPU使用率を出したいとなった後に、思いつくキーワードで検索すると、「なんとなくWMIでいけそう」くらいは分かるが、具体的にどうしたらいいか、にたどり着くのに一苦労した。
(具体的に使えそうなMSの公式ドキュメントに全然たどり着けない & ネット情報でも、それほどWMIの情報が多くない?)
そういうときに、wbemtest
を使ってとりあえずこのクラス、このプロパティで行けそうかも?というところまで絞り込んでおいてから検索してやれば、なにかにたどり着けるかもしれない。(今のところ、絞り込むといっても名前から判断するくらいしかやり方知らないが、、)
参考
wbemtest
を知ったきっかけ
クエリの書き方(MSDocs:WMI Query Language (WQL))
CPU時間⇒CPU使用率の算出の仕方
今回使ったWin32_PerfRawData_PerfProc_Process
クラスは、Win32 プロバイダー
の一種っぽい(けど、下記のWin32プロバイダのページからWin32_PerfRawData_PerfProc_Process
にたどり着けない...)
WMIでパフォーマンスを測るには、という内容(なのだが、知ってる人しかわからない感じ...)
WMIを使ったコーディングのやり方のページ
Discussion